summaryrefslogtreecommitdiffstats
path: root/include/net
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2008-01-31 11:25:51 +1100
committerPaul Mackerras <paulus@samba.org>2008-01-31 11:25:51 +1100
commitbd45ac0c5daae35e7c71138172e63df5cf644cf6 (patch)
tree5eb5a599bf6a9d7a8a34e802db932aa9e9555de4 /include/net
parent4eece4ccf997c0e6d8fdad3d842e37b16b8d705f (diff)
parent5bdeae46be6dfe9efa44a548bd622af325f4bdb4 (diff)
Merge branch 'linux-2.6'
Diffstat (limited to 'include/net')
-rw-r--r--include/net/act_api.h8
-rw-r--r--include/net/addrconf.h44
-rw-r--r--include/net/af_unix.h9
-rw-r--r--include/net/arp.h3
-rw-r--r--include/net/bluetooth/rfcomm.h4
-rw-r--r--include/net/cfg80211.h167
-rw-r--r--include/net/checksum.h25
-rw-r--r--include/net/dsfield.h6
-rw-r--r--include/net/dst.h23
-rw-r--r--include/net/fib_rules.h9
-rw-r--r--include/net/flow.h1
-rw-r--r--include/net/gen_stats.h6
-rw-r--r--include/net/ieee80211.h6
-rw-r--r--include/net/if_inet6.h11
-rw-r--r--include/net/inet_ecn.h8
-rw-r--r--include/net/inet_frag.h33
-rw-r--r--include/net/inet_hashtables.h71
-rw-r--r--include/net/inet_timewait_sock.h14
-rw-r--r--include/net/ip.h30
-rw-r--r--include/net/ip6_fib.h27
-rw-r--r--include/net/ip6_route.h4
-rw-r--r--include/net/ip_fib.h73
-rw-r--r--include/net/ip_vs.h5
-rw-r--r--include/net/ipip.h5
-rw-r--r--include/net/ipv6.h43
-rw-r--r--include/net/irda/irda_device.h13
-rw-r--r--include/net/mac80211.h272
-rw-r--r--include/net/neighbour.h25
-rw-r--r--include/net/net_namespace.h34
-rw-r--r--include/net/netevent.h2
-rw-r--r--include/net/netfilter/ipv6/nf_conntrack_ipv6.h4
-rw-r--r--include/net/netfilter/nf_conntrack.h7
-rw-r--r--include/net/netfilter/nf_conntrack_core.h12
-rw-r--r--include/net/netfilter/nf_conntrack_expect.h4
-rw-r--r--include/net/netfilter/nf_conntrack_helper.h4
-rw-r--r--include/net/netfilter/nf_conntrack_l3proto.h5
-rw-r--r--include/net/netfilter/nf_conntrack_tuple.h17
-rw-r--r--include/net/netfilter/nf_log.h59
-rw-r--r--include/net/netfilter/nf_nat.h5
-rw-r--r--include/net/netfilter/nf_nat_protocol.h18
-rw-r--r--include/net/netfilter/nf_queue.h34
-rw-r--r--include/net/netfilter/xt_rateest.h17
-rw-r--r--include/net/netlabel.h99
-rw-r--r--include/net/netlink.h18
-rw-r--r--include/net/netns/ipv4.h31
-rw-r--r--include/net/netns/ipv6.h35
-rw-r--r--include/net/netns/packet.h15
-rw-r--r--include/net/netns/unix.h13
-rw-r--r--include/net/pkt_cls.h13
-rw-r--r--include/net/pkt_sched.h2
-rw-r--r--include/net/protocol.h2
-rw-r--r--include/net/raw.h40
-rw-r--r--include/net/rawv6.h19
-rw-r--r--include/net/route.h21
-rw-r--r--include/net/sch_generic.h10
-rw-r--r--include/net/sctp/checksum.h78
-rw-r--r--include/net/sctp/constants.h36
-rw-r--r--include/net/sctp/sctp.h10
-rw-r--r--include/net/sctp/structs.h39
-rw-r--r--include/net/snmp.h28
-rw-r--r--include/net/sock.h262
-rw-r--r--include/net/tcp.h134
-rw-r--r--include/net/transp_v6.h20
-rw-r--r--include/net/udp.h36
-rw-r--r--include/net/udplite.h3
-rw-r--r--include/net/xfrm.h284
66 files changed, 1653 insertions, 762 deletions
diff --git a/include/net/act_api.h b/include/net/act_api.h
index 68b4eaf7719..565eed8fe49 100644
--- a/include/net/act_api.h
+++ b/include/net/act_api.h
@@ -89,7 +89,7 @@ struct tc_action_ops {
int (*dump)(struct sk_buff *, struct tc_action *, int, int);
int (*cleanup)(struct tc_action *, int bind);
int (*lookup)(struct tc_action *, u32);
- int (*init)(struct rtattr *, struct rtattr *, struct tc_action *, int , int);
+ int (*init)(struct nlattr *, struct nlattr *, struct tc_action *, int , int);
int (*walk)(struct sk_buff *, struct netlink_callback *, int, struct tc_action *);
};
@@ -104,7 +104,7 @@ extern u32 tcf_hash_new_index(u32 *idx_gen, struct tcf_hashinfo *hinfo);
extern int tcf_hash_search(struct tc_action *a, u32 index);
extern struct tcf_common *tcf_hash_check(u32 index, struct tc_action *a,
int bind, struct tcf_hashinfo *hinfo);
-extern struct tcf_common *tcf_hash_create(u32 index, struct rtattr *est,
+extern struct tcf_common *tcf_hash_create(u32 index, struct nlattr *est,
struct tc_action *a, int size,
int bind, u32 *idx_gen,
struct tcf_hashinfo *hinfo);
@@ -114,8 +114,8 @@ extern int tcf_register_action(struct tc_action_ops *a);
extern int tcf_unregister_action(struct tc_action_ops *a);
extern void tcf_action_destroy(struct tc_action *a, int bind);
extern int tcf_action_exec(struct sk_buff *skb, struct tc_action *a, struct tcf_result *res);
-extern struct tc_action *tcf_action_init(struct rtattr *rta, struct rtattr *est, char *n, int ovr, int bind, int *err);
-extern struct tc_action *tcf_action_init_1(struct rtattr *rta, struct rtattr *est, char *n, int ovr, int bind, int *err);
+extern struct tc_action *tcf_action_init(struct nlattr *nla, struct nlattr *est, char *n, int ovr, int bind);
+extern struct tc_action *tcf_action_init_1(struct nlattr *nla, struct nlattr *est, char *n, int ovr, int bind);
extern int tcf_action_dump(struct sk_buff *skb, struct tc_action *a, int, int);
extern int tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int, int);
extern int tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int, int);
diff --git a/include/net/addrconf.h b/include/net/addrconf.h
index 33b593e1744..496503c0384 100644
--- a/include/net/addrconf.h
+++ b/include/net/addrconf.h
@@ -17,6 +17,7 @@
#define IPV6_MAX_ADDRESSES 16
+#include <linux/in.h>
#include <linux/in6.h>
struct prefix_info {
@@ -58,15 +59,20 @@ extern int addrconf_add_ifaddr(void __user *arg);
extern int addrconf_del_ifaddr(void __user *arg);
extern int addrconf_set_dstaddr(void __user *arg);
-extern int ipv6_chk_addr(struct in6_addr *addr,
+extern int ipv6_chk_addr(struct net *net,
+ struct in6_addr *addr,
struct net_device *dev,
int strict);
+
#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
-extern int ipv6_chk_home_addr(struct in6_addr *addr);
+extern int ipv6_chk_home_addr(struct net *net,
+ struct in6_addr *addr);
#endif
-extern struct inet6_ifaddr * ipv6_get_ifaddr(struct in6_addr *addr,
- struct net_device *dev,
- int strict);
+extern struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net,
+ struct in6_addr *addr,
+ struct net_device *dev,
+ int strict);
+
extern int ipv6_get_saddr(struct dst_entry *dst,
struct in6_addr *daddr,
struct in6_addr *saddr);
@@ -84,6 +90,14 @@ extern void addrconf_leave_solict(struct inet6_dev *idev,
struct in6_addr *addr);
/*
+ * IPv6 Address Label subsystem (addrlabel.c)
+ */
+extern int ipv6_addr_label_init(void);
+extern void ipv6_addr_label_rtnl_register(void);
+extern u32 ipv6_addr_label(const struct in6_addr *addr,
+ int type, int ifindex);
+
+/*
* multicast prototypes (mcast.c)
*/
extern int ipv6_sock_mc_join(struct sock *sk, int ifindex,
@@ -241,6 +255,26 @@ static inline int ipv6_addr_is_ll_all_routers(const struct in6_addr *addr)
addr->s6_addr32[3] == htonl(0x00000002));
}
+static inline int ipv6_isatap_eui64(u8 *eui, __be32 addr)
+{
+ eui[0] = (ipv4_is_zeronet(addr) || ipv4_is_private_10(addr) ||
+ ipv4_is_loopback(addr) || ipv4_is_linklocal_169(addr) ||
+ ipv4_is_private_172(addr) || ipv4_is_test_192(addr) ||
+ ipv4_is_anycast_6to4(addr) || ipv4_is_private_192(addr) ||
+ ipv4_is_test_198(addr) || ipv4_is_multicast(addr) ||
+ ipv4_is_lbcast(addr)) ? 0x00 : 0x02;
+ eui[1] = 0;
+ eui[2] = 0x5E;
+ eui[3] = 0xFE;
+ memcpy (eui+4, &addr, 4);
+ return 0;
+}
+
+static inline int ipv6_addr_is_isatap(const struct in6_addr *addr)
+{
+ return ((addr->s6_addr32[2] | htonl(0x02000000)) == htonl(0x02005EFE));
+}
+
#ifdef CONFIG_PROC_FS
extern int if6_proc_init(void);
extern void if6_proc_exit(void);
diff --git a/include/net/af_unix.h b/include/net/af_unix.h
index a1c805d7f48..2dfa96b0575 100644
--- a/include/net/af_unix.h
+++ b/include/net/af_unix.h
@@ -59,12 +59,11 @@ struct unix_sock {
#define unix_sk(__sk) ((struct unix_sock *)__sk)
#ifdef CONFIG_SYSCTL
-extern int sysctl_unix_max_dgram_qlen;
-extern void unix_sysctl_register(void);
-extern void unix_sysctl_unregister(void);
+extern int unix_sysctl_register(struct net *net);
+extern void unix_sysctl_unregister(struct net *net);
#else
-static inline void unix_sysctl_register(void) {}
-static inline void unix_sysctl_unregister(void) {}
+static inline int unix_sysctl_register(struct net *net) { return 0; }
+static inline void unix_sysctl_unregister(struct net *net) {}
#endif
#endif
#endif
diff --git a/include/net/arp.h b/include/net/arp.h
index f0266456860..752eb47b267 100644
--- a/include/net/arp.h
+++ b/include/net/arp.h
@@ -5,13 +5,12 @@
#include <linux/if_arp.h>
#include <net/neighbour.h>
-#define HAVE_ARP_CREATE
extern struct neigh_table arp_tbl;
extern void arp_init(void);
extern int arp_find(unsigned char *haddr, struct sk_buff *skb);
-extern int arp_ioctl(unsigned int cmd, void __user *arg);
+extern int arp_ioctl(struct net *net, unsigned int cmd, void __user *arg);
extern void arp_send(int type, int ptype, __be32 dest_ip,
struct net_device *dev, __be32 src_ip,
unsigned char *dest_hw, unsigned char *src_hw, unsigned char *th);
diff --git a/include/net/bluetooth/rfcomm.h b/include/net/bluetooth/rfcomm.h
index 25aa575db80..98ec7a32068 100644
--- a/include/net/bluetooth/rfcomm.h
+++ b/include/net/bluetooth/rfcomm.h
@@ -252,8 +252,8 @@ static inline void rfcomm_dlc_put(struct rfcomm_dlc *d)
rfcomm_dlc_free(d);
}
-extern void FASTCALL(__rfcomm_dlc_throttle(struct rfcomm_dlc *d));
-extern void FASTCALL(__rfcomm_dlc_unthrottle(struct rfcomm_dlc *d));
+extern void __rfcomm_dlc_throttle(struct rfcomm_dlc *d);
+extern void __rfcomm_dlc_unthrottle(struct rfcomm_dlc *d);
static inline void rfcomm_dlc_throttle(struct rfcomm_dlc *d)
{
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index d30960e1755..bcc480b8892 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -49,6 +49,120 @@ extern int ieee80211_radiotap_iterator_next(
struct ieee80211_radiotap_iterator *iterator);
+ /**
+ * struct key_params - key information
+ *
+ * Information about a key
+ *
+ * @key: key material
+ * @key_len: length of key material
+ * @cipher: cipher suite selector
+ * @seq: sequence counter (IV/PN) for TKIP and CCMP keys, only used
+ * with the get_key() callback, must be in little endian,
+ * length given by @seq_len.
+ */
+struct key_params {
+ u8 *key;
+ u8 *seq;
+ int key_len;
+ int seq_len;
+ u32 cipher;
+};
+
+/**
+ * struct beacon_parameters - beacon parameters
+ *
+ * Used to configure the beacon for an interface.
+ *
+ * @head: head portion of beacon (before TIM IE)
+ * or %NULL if not changed
+ * @tail: tail portion of beacon (after TIM IE)
+ * or %NULL if not changed
+ * @interval: beacon interval or zero if not changed
+ * @dtim_period: DTIM period or zero if not changed
+ * @head_len: length of @head
+ * @tail_len: length of @tail
+ */
+struct beacon_parameters {
+ u8 *head, *tail;
+ int interval, dtim_period;
+ int head_len, tail_len;
+};
+
+/**
+ * enum station_flags - station flags
+ *
+ * Station capability flags. Note that these must be the bits
+ * according to the nl80211 flags.
+ *
+ * @STATION_FLAG_CHANGED: station flags were changed
+ * @STATION_FLAG_AUTHORIZED: station is authorized to send frames (802.1X)
+ * @STATION_FLAG_SHORT_PREAMBLE: station is capable of receiving frames
+ * with short preambles
+ * @STATION_FLAG_WME: station is WME/QoS capable
+ */
+enum station_flags {
+ STATION_FLAG_CHANGED = 1<<0,
+ STATION_FLAG_AUTHORIZED = 1<<NL80211_STA_FLAG_AUTHORIZED,
+ STATION_FLAG_SHORT_PREAMBLE = 1<<NL80211_STA_FLAG_SHORT_PREAMBLE,
+ STATION_FLAG_WME = 1<<NL80211_STA_FLAG_WME,
+};
+
+/**
+ * struct station_parameters - station parameters
+ *
+ * Used to change and create a new station.
+ *
+ * @vlan: vlan interface station should belong to
+ * @supported_rates: supported rates in IEEE 802.11 format
+ * (or NULL for no change)
+ * @supported_rates_len: number of supported rates
+ * @station_flags: station flags (see &enum station_flags)
+ * @listen_interval: listen interval or -1 for no change
+ * @aid: AID or zero for no change
+ */
+struct station_parameters {
+ u8 *supported_rates;
+ struct net_device *vlan;
+ u32 station_flags;
+ int listen_interval;
+ u16 aid;
+ u8 supported_rates_len;
+};
+
+/**
+ * enum station_stats_flags - station statistics flags
+ *
+ * Used by the driver to indicate which info in &struct station_stats
+ * it has filled in during get_station().
+ *
+ * @STATION_STAT_INACTIVE_TIME: @inactive_time filled
+ * @STATION_STAT_RX_BYTES: @rx_bytes filled
+ * @STATION_STAT_TX_BYTES: @tx_bytes filled
+ */
+enum station_stats_flags {
+ STATION_STAT_INACTIVE_TIME = 1<<0,
+ STATION_STAT_RX_BYTES = 1<<1,
+ STATION_STAT_TX_BYTES = 1<<2,
+};
+
+/**
+ * struct station_stats - station statistics
+ *
+ * Station information filled by driver for get_station().
+ *
+ * @filled: bitflag of flags from &enum station_stats_flags
+ * @inactive_time: time since last station activity (tx/rx) in milliseconds
+ * @rx_bytes: bytes received from this station
+ * @tx_bytes: bytes transmitted to this station
+ */
+struct station_stats {
+ u32 filled;
+ u32 inactive_time;
+ u32 rx_bytes;
+ u32 tx_bytes;
+};
+
/* from net/wireless.h */
struct wiphy;
@@ -71,6 +185,31 @@ struct wiphy;
*
* @change_virtual_intf: change type of virtual interface
*
+ * @add_key: add a key with the given parameters. @mac_addr will be %NULL
+ * when adding a group key.
+ *
+ * @get_key: get information about the key with the given parameters.
+ * @mac_addr will be %NULL when requesting information for a group
+ * key. All pointers given to the @callback function need not be valid
+ * after it returns.
+ *
+ * @del_key: remove a key given the @mac_addr (%NULL for a group key)
+ * and @key_index
+ *
+ * @set_default_key: set the default key on an interface
+ *
+ * @add_beacon: Add a beacon with given parameters, @head, @interval
+ * and @dtim_period will be valid, @tail is optional.
+ * @set_beacon: Change the beacon parameters for an access point mode
+ * interface. This should reject the call when no beacon has been
+ * configured.
+ * @del_beacon: Remove beacon configuration and stop sending the beacon.
+ *
+ * @add_station: Add a new station.
+ *
+ * @del_station: Remove a station; @mac may be NULL to remove all stations.
+ *
+ * @change_station: Modify a given station.
*/
struct cfg80211_ops {
int (*add_virtual_intf)(struct wiphy *wiphy, char *name,
@@ -78,6 +217,34 @@ struct cfg80211_ops {
int (*del_virtual_intf)(struct wiphy *wiphy, int ifindex);
int (*change_virtual_intf)(struct wiphy *wiphy, int ifindex,
enum nl80211_iftype type);
+
+ int (*add_key)(struct wiphy *wiphy, struct net_device *netdev,
+ u8 key_index, u8 *mac_addr,
+ struct key_params *params);
+ int (*get_key)(struct wiphy *wiphy, struct net_device *netdev,
+ u8 key_index, u8 *mac_addr, void *cookie,
+ void (*callback)(void *cookie, struct key_params*));
+ int (*del_key)(struct wiphy *wiphy, struct net_device *netdev,
+ u8 key_index, u8 *mac_addr);
+ int (*set_default_key)(struct wiphy *wiphy,
+ struct net_device *netdev,
+ u8 key_index);
+
+ int (*add_beacon)(struct wiphy *wiphy, struct net_device *dev,
+ struct beacon_parameters *info);
+ int (*set_beacon)(struct wiphy *wiphy, struct net_device *dev,
+ struct beacon_parameters *info);
+ int (*del_beacon)(struct wiphy *wiphy, struct net_device *dev);
+
+
+ int (*add_station)(struct wiphy *wiphy, struct net_device *dev,
+ u8 *mac, struct station_parameters *params);
+ int (*del_station)(struct wiphy *wiphy, struct net_device *dev,
+ u8 *mac);
+ int (*change_station)(struct wiphy *wiphy, struct net_device *dev,
+ u8 *mac, struct station_parameters *params);
+ int (*get_station)(struct wiphy *wiphy, struct net_device *dev,
+ u8 *mac, struct station_stats *stats);
};
#endif /* __NET_CFG80211_H */
diff --git a/include/net/checksum.h b/include/net/checksum.h
index 124246172a8..07602b7fa21 100644
--- a/include/net/checksum.h
+++ b/include/net/checksum.h
@@ -93,4 +93,29 @@ static inline __wsum csum_unfold(__sum16 n)
}
#define CSUM_MANGLED_0 ((__force __sum16)0xffff)
+
+static inline void csum_replace4(__sum16 *sum, __be32 from, __be32 to)
+{
+ __be32 diff[] = { ~from, to };
+
+ *sum = csum_fold(csum_partial((char *)diff, sizeof(diff), ~csum_unfold(*sum)));
+}
+
+static inline void csum_replace2(__sum16 *sum, __be16 from, __be16 to)
+{
+ csum_replace4(sum, (__force __be32)from, (__force __be32)to);
+}
+
+struct sk_buff;
+extern void inet_proto_csum_replace4(__sum16 *sum, struct sk_buff *skb,
+ __be32 from, __be32 to, int pseudohdr);
+
+static inline void inet_proto_csum_replace2(__sum16 *sum, struct sk_buff *skb,
+ __be16 from, __be16 to,
+ int pseudohdr)
+{
+ inet_proto_csum_replace4(sum, skb, (__force __be32)from,
+ (__force __be32)to, pseudohdr);
+}
+
#endif
diff --git a/include/net/dsfield.h b/include/net/dsfield.h
index eb65bf2e250..8a8d4e06900 100644
--- a/include/net/dsfield.h
+++ b/include/net/dsfield.h
@@ -12,15 +12,15 @@
#include <asm/byteorder.h>
-static inline __u8 ipv4_get_dsfield(struct iphdr *iph)
+static inline __u8 ipv4_get_dsfield(const struct iphdr *iph)
{
return iph->tos;
}
-static inline __u8 ipv6_get_dsfield(struct ipv6hdr *ipv6h)
+static inline __u8 ipv6_get_dsfield(const struct ipv6hdr *ipv6h)
{
- return ntohs(*(__be16 *) ipv6h) >> 4;
+ return ntohs(*(const __be16 *)ipv6h) >> 4;
}
diff --git a/include/net/dst.h b/include/net/dst.h
index 2f65e894b82..e3ac7d0fc4e 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -50,14 +50,17 @@ struct dst_entry
unsigned long expires;
unsigned short header_len; /* more space at head required */
- unsigned short nfheader_len; /* more non-fragment space at head required */
unsigned short trailer_len; /* space to reserve at tail */
u32 metrics[RTAX_MAX];
struct dst_entry *path;
unsigned long rate_last; /* rate limiting for ICMP */
- unsigned long rate_tokens;
+ unsigned int rate_tokens;
+
+#ifdef CONFIG_NET_CLS_ROUTE
+ __u32 tclassid;
+#endif
struct neighbour *neighbour;
struct hh_cache *hh;
@@ -66,10 +69,6 @@ struct dst_entry
int (*input)(struct sk_buff*);
int (*output)(struct sk_buff*);
-#ifdef CONFIG_NET_CLS_ROUTE
- __u32 tclassid;
-#endif
-
struct dst_ops *ops;
unsigned long lastuse;
@@ -81,7 +80,6 @@ struct dst_entry
struct rt6_info *rt6_next;
struct dn_route *dn_next;
};
- char info[0];
};
@@ -91,7 +89,7 @@ struct dst_ops
__be16 protocol;
unsigned gc_thresh;
- int (*gc)(void);
+ int (*gc)(struct dst_ops *ops);
struct dst_entry * (*check)(struct dst_entry *, __u32 cookie);
void (*destroy)(struct dst_entry *);
void (*ifdown)(struct dst_entry *,
@@ -99,10 +97,12 @@ struct dst_ops
struct dst_entry * (*negative_advice)(struct dst_entry *);
void (*link_failure)(struct sk_buff *);
void (*update_pmtu)(struct dst_entry *dst, u32 mtu);
+ int (*local_out)(struct sk_buff *skb);
int entry_size;
atomic_t entries;
struct kmem_cache *kmem_cachep;
+ struct net *dst_net;
};
#ifdef __KERNEL__
@@ -180,6 +180,7 @@ static inline struct dst_entry *dst_pop(struct dst_entry *dst)
return child;
}
+extern int dst_discard(struct sk_buff *skb);
extern void * dst_alloc(struct dst_ops * ops);
extern void __dst_free(struct dst_entry * dst);
extern struct dst_entry *dst_destroy(struct dst_entry * dst);
@@ -264,6 +265,12 @@ static inline struct dst_entry *dst_check(struct dst_entry *dst, u32 cookie)
extern void dst_init(void);
+/* Flags for xfrm_lookup flags argument. */
+enum {
+ XFRM_LOOKUP_WAIT = 1 << 0,
+ XFRM_LOOKUP_ICMP = 1 << 1,
+};
+
struct flowi;
#ifndef CONFIG_XFRM
static inline int xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl,
diff --git a/include/net/fib_rules.h b/include/net/fib_rules.h
index 41a301e3864..34349f9f433 100644
--- a/include/net/fib_rules.h
+++ b/include/net/fib_rules.h
@@ -22,6 +22,7 @@ struct fib_rule
u32 target;
struct fib_rule * ctarget;
struct rcu_head rcu;
+ struct net * fr_net;
};
struct fib_lookup_arg
@@ -56,7 +57,7 @@ struct fib_rules_ops
int (*fill)(struct fib_rule *, struct sk_buff *,
struct nlmsghdr *,
struct fib_rule_hdr *);
- u32 (*default_pref)(void);
+ u32 (*default_pref)(struct fib_rules_ops *ops);
size_t (*nlmsg_payload)(struct fib_rule *);
/* Called after modifications to the rules set, must flush
@@ -67,6 +68,7 @@ struct fib_rules_ops
const struct nla_policy *policy;
struct list_head rules_list;
struct module *owner;
+ struct net *fro_net;
};
#define FRA_GENERIC_POLICY \
@@ -101,8 +103,9 @@ static inline u32 frh_get_table(struct fib_rule_hdr *frh, struct nlattr **nla)
return frh->table;
}
-extern int fib_rules_register(struct fib_rules_ops *);
-extern int fib_rules_unregister(struct fib_rules_ops *);
+extern int fib_rules_register(struct fib_rules_ops *);
+extern void fib_rules_unregister(struct fib_rules_ops *);
+extern void fib_rules_cleanup_ops(struct fib_rules_ops *);
extern int fib_rules_lookup(struct fib_rules_ops *,
struct flowi *, int flags,
diff --git a/include/net/flow.h b/include/net/flow.h
index af59fa5cc1f..ad16e0076c8 100644
--- a/include/net/flow.h
+++ b/include/net/flow.h
@@ -48,7 +48,6 @@ struct flowi {
__u8 proto;
__u8 flags;
-#define FLOWI_FLAG_MULTIPATHOLDROUTE 0x01
union {
struct {
__be16 sport;
diff --git a/include/net/gen_stats.h b/include/net/gen_stats.h
index 0b95cf031d6..8cd8185fa2e 100644
--- a/include/net/gen_stats.h
+++ b/include/net/gen_stats.h
@@ -10,7 +10,7 @@ struct gnet_dump
{
spinlock_t * lock;
struct sk_buff * skb;
- struct rtattr * tail;
+ struct nlattr * tail;
/* Backward compatability */
int compat_tc_stats;
@@ -39,11 +39,11 @@ extern int gnet_stats_finish_copy(struct gnet_dump *d);
extern int gen_new_estimator(struct gnet_stats_basic *bstats,
struct gnet_stats_rate_est *rate_est,
- spinlock_t *stats_lock, struct rtattr *opt);
+ spinlock_t *stats_lock, struct nlattr *opt);
extern void gen_kill_estimator(struct gnet_stats_basic *bstats,
struct gnet_stats_rate_est *rate_est);
extern int gen_replace_estimator(struct gnet_stats_basic *bstats,
struct gnet_stats_rate_est *rate_est,
- spinlock_t *stats_lock, struct rtattr *opt);
+ spinlock_t *stats_lock, struct nlattr *opt);
#endif
diff --git a/include/net/ieee80211.h b/include/net/ieee80211.h
index d8ae48439f1..285b2adfa64 100644
--- a/include/net/ieee80211.h
+++ b/include/net/ieee80211.h
@@ -677,7 +677,7 @@ struct ieee80211_probe_request {
struct ieee80211_probe_response {
struct ieee80211_hdr_3addr header;
- u32 time_stamp[2];
+ __le32 time_stamp[2];
__le16 beacon_interval;
__le16 capability;
/* SSID, supported rates, FH params, DS params,
@@ -718,8 +718,8 @@ struct ieee80211_txb {
u8 encrypted;
u8 rts_included;
u8 reserved;
- __le16 frag_size;
- __le16 payload_size;
+ u16 frag_size;
+ u16 payload_size;
struct sk_buff *fragments[0];
};
diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h
index 448eccb2063..b24508abb85 100644
--- a/include/net/if_inet6.h
+++ b/include/net/if_inet6.h
@@ -269,18 +269,21 @@ static inline void ipv6_arcnet_mc_map(const struct in6_addr *addr, char *buf)
buf[0] = 0x00;
}
-static inline void ipv6_ib_mc_map(struct in6_addr *addr, char *buf)
+static inline void ipv6_ib_mc_map(const struct in6_addr *addr,
+ const unsigned char *broadcast, char *buf)
{
+ unsigned char scope = broadcast[5] & 0xF;
+
buf[0] = 0; /* Reserved */
buf[1] = 0xff; /* Multicast QPN */
buf[2] = 0xff;
buf[3] = 0xff;
buf[4] = 0xff;
- buf[5] = 0x12; /* link local scope */
+ buf[5] = 0x10 | scope; /* scope from broadcast address */
buf[6] = 0x60; /* IPv6 signature */
buf[7] = 0x1b;
- buf[8] = 0; /* P_Key */
- buf[9] = 0;
+ buf[8] = broadcast[8]; /* P_Key */
+ buf[9] = broadcast[9];
memcpy(buf + 10, addr->s6_addr + 6, 10);
}
#endif
diff --git a/include/net/inet_ecn.h b/include/net/inet_ecn.h
index de8399a7977..ba33db05385 100644
--- a/include/net/inet_ecn.h
+++ b/include/net/inet_ecn.h
@@ -83,9 +83,9 @@ static inline void IP_ECN_clear(struct iphdr *iph)
iph->tos &= ~INET_ECN_MASK;
}
-static inline void ipv4_copy_dscp(struct iphdr *outer, struct iphdr *inner)
+static inline void ipv4_copy_dscp(unsigned int dscp, struct iphdr *inner)
{
- u32 dscp = ipv4_get_dsfield(outer) & ~INET_ECN_MASK;
+ dscp &= ~INET_ECN_MASK;
ipv4_change_dsfield(inner, INET_ECN_MASK, dscp);
}
@@ -104,9 +104,9 @@ static inline void IP6_ECN_clear(struct ipv6hdr *iph)
*(__be32*)iph &= ~htonl(INET_ECN_MASK << 20);
}
-static inline void ipv6_copy_dscp(struct ipv6hdr *outer, struct ipv6hdr *inner)
+static inline void ipv6_copy_dscp(unsigned int dscp, struct ipv6hdr *inner)
{
- u32 dscp = ipv6_get_dsfield(outer) & ~INET_ECN_MASK;
+ dscp &= ~INET_ECN_MASK;
ipv6_change_dsfield(inner, INET_ECN_MASK, dscp);
}
diff --git a/include/net/inet_frag.h b/include/net/inet_frag.h
index 954def40897..7374251b978 100644
--- a/include/net/inet_frag.h
+++ b/include/net/inet_frag.h
@@ -1,8 +1,20 @@
#ifndef __NET_FRAG_H__
#define __NET_FRAG_H__
+struct netns_frags {
+ int nqueues;
+ atomic_t mem;
+ struct list_head lru_list;
+
+ /* sysctls */
+ int timeout;
+ int high_thresh;
+ int low_thresh;
+};
+
struct inet_frag_queue {
struct hlist_node list;
+ struct netns_frags *net;
struct list_head lru_list; /* lru list member */
spinlock_t lock;
atomic_t refcnt;
@@ -20,23 +32,13 @@ struct inet_frag_queue {
#define INETFRAGS_HASHSZ 64
-struct inet_frags_ctl {
- int high_thresh;
- int low_thresh;
- int timeout;
- int secret_interval;
-};
-
struct inet_frags {
- struct list_head lru_list;
struct hlist_head hash[INETFRAGS_HASHSZ];
rwlock_t lock;
u32 rnd;
- int nqueues;
int qsize;
- atomic_t mem;
+ int secret_interval;
struct timer_list secret_timer;
- struct inet_frags_ctl *ctl;
unsigned int (*hashfn)(struct inet_frag_queue *);
void (*constructor)(struct inet_frag_queue *q,
@@ -51,12 +53,15 @@ struct inet_frags {
void inet_frags_init(struct inet_frags *);
void inet_frags_fini(struct inet_frags *);
+void inet_frags_init_net(struct netns_frags *nf);
+void inet_frags_exit_net(struct netns_frags *nf, struct inet_frags *f);
+
void inet_frag_kill(struct inet_frag_queue *q, struct inet_frags *f);
void inet_frag_destroy(struct inet_frag_queue *q,
struct inet_frags *f, int *work);
-int inet_frag_evictor(struct inet_frags *f);
-struct inet_frag_queue *inet_frag_find(struct inet_frags *f, void *key,
- unsigned int hash);
+int inet_frag_evictor(struct netns_frags *nf, struct inet_frags *f);
+struct inet_frag_queue *inet_frag_find(struct netns_frags *nf,
+ struct inet_frags *f, void *key, unsigned int hash);
static inline void inet_frag_put(struct inet_frag_queue *q, struct inet_frags *f)
{
diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h
index 37f6cb11212..761bdc01425 100644
--- a/include/net/inet_hashtables.h
+++ b/include/net/inet_hashtables.h
@@ -264,37 +264,14 @@ static inline void inet_listen_unlock(struct inet_hashinfo *hashinfo)
wake_up(&hashinfo->lhash_wait);
}
-static inline void __inet_hash(struct inet_hashinfo *hashinfo,
- struct sock *sk, const int listen_possible)
-{
- struct hlist_head *list;
- rwlock_t *lock;
-
- BUG_TRAP(sk_unhashed(sk));
- if (listen_possible && sk->sk_state == TCP_LISTEN) {
- list = &hashinfo->listening_hash[inet_sk_listen_hashfn(sk)];
- lock = &hashinfo->lhash_lock;
- inet_listen_wlock(hashinfo);
- } else {
- struct inet_ehash_bucket *head;
- sk->sk_hash = inet_sk_ehashfn(sk);
- head = inet_ehash_bucket(hashinfo, sk->sk_hash);
- list = &head->chain;
- lock = inet_ehash_lockp(hashinfo, sk->sk_hash);
- write_lock(lock);
- }
- __sk_add_node(sk, list);
- sock_prot_inc_use(sk->sk_prot);
- write_unlock(lock);
- if (listen_possible && sk->sk_state == TCP_LISTEN)
- wake_up(&hashinfo->lhash_wait);
-}
+extern void __inet_hash(struct inet_hashinfo *hashinfo, struct sock *sk);
+extern void __inet_hash_nolisten(struct inet_hashinfo *hinfo, struct sock *sk);
static inline void inet_hash(struct inet_hashinfo *hashinfo, struct sock *sk)
{
if (sk->sk_state != TCP_CLOSE) {
local_bh_disable();
- __inet_hash(hashinfo, sk, 1);
+ __inet_hash(hashinfo, sk);
local_bh_enable();
}
}
@@ -316,7 +293,7 @@ static inline void inet_unhash(struct inet_hashinfo *hashinfo, struct sock *sk)
}
if (__sk_del_node_init(sk))
- sock_prot_dec_use(sk->sk_prot);
+ sock_prot_inuse_add(sk->sk_prot, -1);
write_unlock_bh(lock);
out:
if (sk->sk_state == TCP_LISTEN)
@@ -397,43 +374,9 @@ typedef __u64 __bitwise __addrpair;
*
* Local BH must be disabled here.
*/
-static inline struct sock *
- __inet_lookup_established(struct inet_hashinfo *hashinfo,
- const __be32 saddr, const __be16 sport,
- const __be32 daddr, const u16 hnum,
- const int dif)
-{
- INET_ADDR_COOKIE(acookie, saddr, daddr)
- const __portpair ports = INET_COMBINED_PORTS(sport, hnum);
- struct sock *sk;
- const struct hlist_node *node;
- /* Optimize here for direct hit, only listening connections can
- * have wildcards anyways.
- */
- unsigned int hash = inet_ehashfn(daddr, hnum, saddr, sport);
- struct inet_ehash_bucket *head = inet_ehash_bucket(hashinfo, hash);
- rwlock_t *lock = inet_ehash_lockp(hashinfo, hash);
-
- prefetch(head->chain.first);
- read_lock(lock);
- sk_for_each(sk, node, &head->chain) {
- if (INET_MATCH(sk, hash, acookie, saddr, daddr, ports, dif))
- goto hit; /* You sunk my battleship! */
- }
-
- /* Must check for a TIME_WAIT'er before going to listener hash. */
- sk_for_each(sk, node, &head->twchain) {
- if (INET_TW_MATCH(sk, hash, acookie, saddr, daddr, ports, dif))
- goto hit;
- }
- sk = NULL;
-out:
- read_unlock(lock);
- return sk;
-hit:
- sock_hold(sk);
- goto out;
-}
+extern struct sock * __inet_lookup_established(struct inet_hashinfo *hashinfo,
+ const __be32 saddr, const __be16 sport,
+ const __be32 daddr, const u16 hnum, const int dif);
static inline struct sock *
inet_lookup_established(struct inet_hashinfo *hashinfo,
diff --git a/include/net/inet_timewait_sock.h b/include/net/inet_timewait_sock.h
index abaff059727..67e925065aa 100644
--- a/include/net/inet_timewait_sock.h
+++ b/include/net/inet_timewait_sock.h
@@ -193,19 +193,7 @@ static inline __be32 inet_rcv_saddr(const struct sock *sk)
inet_sk(sk)->rcv_saddr : inet_twsk(sk)->tw_rcv_saddr;
}
-static inline void inet_twsk_put(struct inet_timewait_sock *tw)
-{
- if (atomic_dec_and_test(&tw->tw_refcnt)) {
- struct module *owner = tw->tw_prot->owner;
- twsk_destructor((struct sock *)tw);
-#ifdef SOCK_REFCNT_DEBUG
- printk(KERN_DEBUG "%s timewait_sock %p released\n",
- tw->tw_prot->name, tw);
-#endif
- kmem_cache_free(tw->tw_prot->twsk_prot->twsk_slab, tw);
- module_put(owner);
- }
-}
+extern void inet_twsk_put(struct inet_timewait_sock *tw);
extern struct inet_timewait_sock *inet_twsk_alloc(const struct sock *sk,
const int state);
diff --git a/include/net/ip.h b/include/net/ip.h
index 840dd91b513..9f50d4f1f15 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -82,8 +82,6 @@ struct packet_type;
struct rtable;
struct sockaddr;
-extern void ip_mc_dropsocket(struct sock *);
-extern void ip_mc_dropdevice(struct net_device *dev);
extern int igmp_mc_proc_init(void);
/*
@@ -102,6 +100,8 @@ extern int ip_mc_output(struct sk_buff *skb);
extern int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *));
extern int ip_do_nat(struct sk_buff *skb);
extern void ip_send_check(struct iphdr *ip);
+extern int __ip_local_out(struct sk_buff *skb);
+extern int ip_local_out(struct sk_buff *skb);
extern int ip_queue_xmit(struct sk_buff *skb, int ipfragok);
extern void ip_init(void);
extern int ip_append_data(struct sock *sk,
@@ -169,7 +169,7 @@ DECLARE_SNMP_STAT(struct linux_mib, net_statistics);
#define NET_ADD_STATS_USER(field, adnd) SNMP_ADD_STATS_USER(net_statistics, field, adnd)
extern unsigned long snmp_fold_field(void *mib[], int offt);
-extern int snmp_mib_init(void *ptr[2], size_t mibsize, size_t mibalign);
+extern int snmp_mib_init(void *ptr[2], size_t mibsize);
extern void snmp_mib_free(void *ptr[2]);
extern void inet_get_local_port_range(int *low, int *high);
@@ -177,10 +177,7 @@ extern void inet_get_local_port_range(int *low, int *high);
extern int sysctl_ip_default_ttl;
extern int sysctl_ip_nonlocal_bind;
-/* From ip_fragment.c */
-struct inet_frags_ctl;
-extern struct inet_frags_ctl ip4_frags_ctl;
-extern int sysctl_ipfrag_max_dist;
+extern struct ctl_path net_ipv4_ctl_path[];
/* From inetpeer.c */
extern int inet_peer_threshold;
@@ -266,20 +263,22 @@ static inline void ip_eth_mc_map(__be32 naddr, char *buf)
* Leave P_Key as 0 to be filled in by driver.
*/
-static inline void ip_ib_mc_map(__be32 naddr, char *buf)
+static inline void ip_ib_mc_map(__be32 naddr, const unsigned char *broadcast, char *buf)
{
__u32 addr;
+ unsigned char scope = broadcast[5] & 0xF;
+
buf[0] = 0; /* Reserved */
buf[1] = 0xff; /* Multicast QPN */
buf[2] = 0xff;
buf[3] = 0xff;
addr = ntohl(naddr);
buf[4] = 0xff;
- buf[5] = 0x12; /* link local scope */
+ buf[5] = 0x10 | scope; /* scope from broadcast address */
buf[6] = 0x40; /* IPv4 signature */
buf[7] = 0x1b;
- buf[8] = 0; /* P_Key */
- buf[9] = 0;
+ buf[8] = broadcast[8]; /* P_Key */
+ buf[9] = broadcast[9];
buf[10] = 0;
buf[11] = 0;
buf[12] = 0;
@@ -317,7 +316,7 @@ static __inline__ void inet_reset_saddr(struct sock *sk)
extern int ip_call_ra_chain(struct sk_buff *skb);
/*
- * Functions provided by ip_fragment.o
+ * Functions provided by ip_fragment.c
*/
enum ip_defrag_users
@@ -332,15 +331,14 @@ enum ip_defrag_users
};
int ip_defrag(struct sk_buff *skb, u32 user);
-int ip_frag_mem(void);
-int ip_frag_nqueues(void);
+int ip_frag_mem(struct net *net);
+int ip_frag_nqueues(struct net *net);
/*
* Functions provided by ip_forward.c
*/
extern int ip_forward(struct sk_buff *skb);
-extern int ip_net_unreachable(struct sk_buff *skb);
/*
* Functions provided by ip_options.c
@@ -391,6 +389,4 @@ int ipv4_doint_and_flush_strategy(ctl_table *table, int __user *name, int nlen,
extern int ip_misc_proc_init(void);
#endif
-extern struct ctl_table ipv4_table[];
-
#endif /* _IP_H */
diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h
index 857821360bb..d8d85b13364 100644
--- a/include/net/ip6_fib.h
+++ b/include/net/ip6_fib.h
@@ -99,16 +99,21 @@ struct rt6_info
u32 rt6i_flags;
u32 rt6i_metric;
atomic_t rt6i_ref;
- struct fib6_table *rt6i_table;
- struct rt6key rt6i_dst;
- struct rt6key rt6i_src;
+ /* more non-fragment space at head required */
+ unsigned short rt6i_nfheader_len;
u8 rt6i_protocol;
+ struct fib6_table *rt6i_table;
+
+ struct rt6key rt6i_dst;
+
#ifdef CONFIG_XFRM
u32 rt6i_flow_cache_genid;
#endif
+
+ struct rt6key rt6i_src;
};
static inline struct inet6_dev *ip6_dst_idev(struct dst_entry *dst)
@@ -219,10 +224,20 @@ extern void fib6_run_gc(unsigned long dummy);
extern void fib6_gc_cleanup(void);
-extern void fib6_init(void);
+extern int fib6_init(void);
-extern void fib6_rules_init(void);
+#ifdef CONFIG_IPV6_MULTIPLE_TABLES
+extern int fib6_rules_init(void);
extern void fib6_rules_cleanup(void);
-
+#else
+static inline int fib6_rules_init(void)
+{
+ return 0;
+}
+static inline void fib6_rules_cleanup(void)
+{
+ return ;
+}
+#endif
#endif
#endif
diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h
index 5456fdd6d04..faac0eee1ef 100644
--- a/include/net/ip6_route.h
+++ b/include/net/ip6_route.h
@@ -43,14 +43,12 @@ extern struct rt6_info ip6_prohibit_entry;
extern struct rt6_info ip6_blk_hole_entry;
#endif
-extern int ip6_rt_gc_interval;
-
extern void ip6_route_input(struct sk_buff *skb);
extern struct dst_entry * ip6_route_output(struct sock *sk,
struct flowi *fl);
-extern void ip6_route_init(void);
+extern int ip6_route_init(void);
extern void ip6_route_cleanup(void);
extern int ipv6_route_ioctl(unsigned int cmd, void __user *arg);
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
index ed514bfb61b..9daa60b544b 100644
--- a/include/net/ip_fib.h
+++ b/include/net/ip_fib.h
@@ -125,11 +125,15 @@ struct fib_result_nl {
#define FIB_RES_NH(res) ((res).fi->fib_nh[(res).nh_sel])
#define FIB_RES_RESET(res) ((res).nh_sel = 0)
+#define FIB_TABLE_HASHSZ 2
+
#else /* CONFIG_IP_ROUTE_MULTIPATH */
#define FIB_RES_NH(res) ((res).fi->fib_nh[0])
#define FIB_RES_RESET(res)
+#define FIB_TABLE_HASHSZ 256
+
#endif /* CONFIG_IP_ROUTE_MULTIPATH */
#define FIB_RES_PREFSRC(res) ((res).fi->fib_prefsrc ? : __fib_res_prefsrc(&res))
@@ -141,6 +145,7 @@ struct fib_table {
struct hlist_node tb_hlist;
u32 tb_id;
unsigned tb_stamp;
+ int tb_default;
int (*tb_lookup)(struct fib_table *tb, const struct flowi *flp, struct fib_result *res);
int (*tb_insert)(struct fib_table *, struct fib_config *);
int (*tb_delete)(struct fib_table *, struct fib_config *);
@@ -155,50 +160,51 @@ struct fib_table {
#ifndef CONFIG_IP_MULTIPLE_TABLES
-extern struct fib_table *ip_fib_local_table;
-extern struct fib_table *ip_fib_main_table;
+#define TABLE_LOCAL_INDEX 0
+#define TABLE_MAIN_INDEX 1
-static inline struct fib_table *fib_get_table(u32 id)
+static inline struct fib_table *fib_get_table(struct net *net, u32 id)
{
- if (id != RT_TABLE_LOCAL)
- return ip_fib_main_table;
- return ip_fib_local_table;
-}
+ struct hlist_head *ptr;
-static inline struct fib_table *fib_new_table(u32 id)
-{
- return fib_get_table(id);
+ ptr = id == RT_TABLE_LOCAL ?
+ &net->ipv4.fib_table_hash[TABLE_LOCAL_INDEX] :
+ &net->ipv4.fib_table_hash[TABLE_MAIN_INDEX];
+ return hlist_entry(ptr->first, struct fib_table, tb_hlist);
}
-static inline int fib_lookup(const struct flowi *flp, struct fib_result *res)
+static inline struct fib_table *fib_new_table(struct net *net, u32 id)
{
- if (ip_fib_local_table->tb_lookup(ip_fib_local_table, flp, res) &&
- ip_fib_main_table->tb_lookup(ip_fib_main_table, flp, res))
- return -ENETUNREACH;
- return 0;
+ return fib_get_table(net, id);
}
-static inline void fib_select_default(const struct flowi *flp, struct fib_result *res)
+static inline int fib_lookup(struct net *net, const struct flowi *flp,
+ struct fib_result *res)
{
- if (FIB_RES_GW(*res) && FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK)
- ip_fib_main_table->tb_select_default(ip_fib_main_table, flp, res);
+ struct fib_table *table;
+
+ table = fib_get_table(net, RT_TABLE_LOCAL);
+ if (!table->tb_lookup(table, flp, res))
+ return 0;
+
+ table = fib_get_table(net, RT_TABLE_MAIN);
+ if (!table->tb_lookup(table, flp, res))
+ return 0;
+ return -ENETUNREACH;
}
#else /* CONFIG_IP_MULTIPLE_TABLES */
-extern void __init fib4_rules_init(void);
+extern int __net_init fib4_rules_init(struct net *net);
+extern void __net_exit fib4_rules_exit(struct net *net);
#ifdef CONFIG_NET_CLS_ROUTE
extern u32 fib_rules_tclass(struct fib_result *res);
#endif
-#define ip_fib_local_table fib_get_table(RT_TABLE_LOCAL)
-#define ip_fib_main_table fib_get_table(RT_TABLE_MAIN)
-
-extern int fib_lookup(struct flowi *flp, struct fib_result *res);
+extern int fib_lookup(struct net *n, struct flowi *flp, struct fib_result *res);
-extern struct fib_table *fib_new_table(u32 id);
-extern struct fib_table *fib_get_table(u32 id);
-extern void fib_select_default(const struct flowi *flp, struct fib_result *res);
+extern struct fib_table *fib_new_table(struct net *net, u32 id);
+extern struct fib_table *fib_get_table(struct net *net, u32 id);
#endif /* CONFIG_IP_MULTIPLE_TABLES */
@@ -207,18 +213,19 @@ extern const struct nla_policy rtm_ipv4_policy[];
extern void ip_fib_init(void);
extern int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif,
struct net_device *dev, __be32 *spec_dst, u32 *itag);
-extern void fib_select_multipath(const struct flowi *flp, struct fib_result *res);
-
-struct rtentry;
+extern void fib_select_default(struct net *net, const struct flowi *flp,
+ struct fib_result *res);
/* Exported by fib_semantics.c */
extern int ip_fib_check_default(__be32 gw, struct net_device *dev);
extern int fib_sync_down(__be32 local, struct net_device *dev, int force);
extern int fib_sync_up(struct net_device *dev);
extern __be32 __fib_res_prefsrc(struct fib_result *res);
+extern void fib_select_multipath(const struct flowi *flp, struct fib_result *res);
-/* Exported by fib_hash.c */
-extern struct fib_table *fib_hash_init(u32 id);
+/* Exported by fib_{hash|trie}.c */
+extern void fib_hash_init(void);
+extern struct fib_table *fib_hash_table(u32 id);
static inline void fib_combine_itag(u32 *itag, struct fib_result *res)
{
@@ -255,8 +262,8 @@ static inline void fib_res_put(struct fib_result *res)
}
#ifdef CONFIG_PROC_FS
-extern int fib_proc_init(void);
-extern void fib_proc_exit(void);
+extern int __net_init fib_proc_init(struct net *net);
+extern void __net_exit fib_proc_exit(struct net *net);
#endif
#endif /* _NET_FIB_H */
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
index 8a7d59be8a0..56f3c94ae62 100644
--- a/include/net/ip_vs.h
+++ b/include/net/ip_vs.h
@@ -9,6 +9,8 @@
#include <asm/types.h> /* For __uXX types */
#include <linux/types.h> /* For __beXX types in userland */
+#include <linux/sysctl.h> /* For ctl_path */
+
#define IP_VS_VERSION_CODE 0x010201
#define NVERSION(version) \
(version >> 16) & 0xFF, \
@@ -676,7 +678,6 @@ extern const char *ip_vs_proto_name(unsigned proto);
extern void ip_vs_init_hash_table(struct list_head *table, int rows);
#define IP_VS_INIT_HASH_TABLE(t) ip_vs_init_hash_table(t, sizeof(t)/sizeof(t[0]))
-#define IP_VS_APP_TYPE_UNSPEC 0
#define IP_VS_APP_TYPE_FTP 1
/*
@@ -735,7 +736,6 @@ extern const char * ip_vs_state_name(__u16 proto, int state);
extern void ip_vs_tcp_conn_listen(struct ip_vs_conn *cp);
extern int ip_vs_check_template(struct ip_vs_conn *ct);
-extern void ip_vs_secure_tcp_set(int on);
extern void ip_vs_random_dropentry(void);
extern int ip_vs_conn_init(void);
extern void ip_vs_conn_cleanup(void);
@@ -856,6 +856,7 @@ extern int sysctl_ip_vs_expire_quiescent_template;
extern int sysctl_ip_vs_sync_threshold[2];
extern int sysctl_ip_vs_nat_icmp_send;
extern struct ip_vs_stats ip_vs_stats;
+extern struct ctl_path net_vs_ctl_path[];
extern struct ip_vs_service *
ip_vs_service_get(__u32 fwmark, __u16 protocol, __be32 vaddr, __be16 vport);
diff --git a/include/net/ipip.h b/include/net/ipip.h
index 7cdc914322f..549e132bca9 100644
--- a/include/net/ipip.h
+++ b/include/net/ipip.h
@@ -2,6 +2,7 @@
#define __NET_IPIP_H 1
#include <linux/if_tunnel.h>
+#include <net/ip.h>
/* Keep error state on tunnel for 30 sec */
#define IPTUNNEL_ERR_TIMEO (30*HZ)
@@ -30,11 +31,9 @@ struct ip_tunnel
int pkt_len = skb->len; \
\
skb->ip_summed = CHECKSUM_NONE; \
- iph->tot_len = htons(skb->len); \
ip_select_ident(iph, &rt->u.dst, NULL); \
- ip_send_check(iph); \
\
- err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev, dst_output);\
+ err = ip_local_out(skb); \
if (net_xmit_eval(err) == 0) { \
stats->tx_bytes += pkt_len; \
stats->tx_packets++; \
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index ae328b680ff..fa80ea48639 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -109,9 +109,10 @@ struct frag_hdr {
#include <net/sock.h>
/* sysctls */
-extern int sysctl_ipv6_bindv6only;
extern int sysctl_mld_max_msf;
+extern struct ctl_path net_ipv6_ctl_path[];
+
#define _DEVINC(statname, modifier, idev, field) \
({ \
struct inet6_dev *_idev = (idev); \
@@ -143,14 +144,6 @@ DECLARE_SNMP_STAT(struct icmpv6msg_mib, icmpv6msg_statistics);
#define ICMP6_INC_STATS_BH(idev, field) _DEVINC(icmpv6, _BH, idev, field)
#define ICMP6_INC_STATS_USER(idev, field) _DEVINC(icmpv6, _USER, idev, field)
-#define ICMP6_INC_STATS_OFFSET_BH(idev, field, offset) ({ \
- struct inet6_dev *_idev = idev; \
- __typeof__(offset) _offset = (offset); \
- if (likely(_idev != NULL)) \
- SNMP_INC_STATS_OFFSET_BH(_idev->stats.icmpv6, field, _offset); \
- SNMP_INC_STATS_OFFSET_BH(icmpv6_statistics, field, _offset); \
-})
-
#define ICMP6MSGOUT_INC_STATS(idev, field) \
_DEVINC(icmpv6msg, , idev, field +256)
#define ICMP6MSGOUT_INC_STATS_BH(idev, field) \
@@ -164,15 +157,6 @@ DECLARE_SNMP_STAT(struct icmpv6msg_mib, icmpv6msg_statistics);
#define ICMP6MSGIN_INC_STATS_USER(idev, field) \
_DEVINC(icmpv6msg, _USER, idev, field)
-DECLARE_SNMP_STAT(struct udp_mib, udp_stats_in6);
-DECLARE_SNMP_STAT(struct udp_mib, udplite_stats_in6);
-#define UDP6_INC_STATS_BH(field, is_udplite) do { \
- if (is_udplite) SNMP_INC_STATS_BH(udplite_stats_in6, field); \
- else SNMP_INC_STATS_BH(udp_stats_in6, field); } while(0)
-#define UDP6_INC_STATS_USER(field, is_udplite) do { \
- if (is_udplite) SNMP_INC_STATS_USER(udplite_stats_in6, field); \
- else SNMP_INC_STATS_USER(udp_stats_in6, field); } while(0)
-
struct ip6_ra_chain
{
struct ip6_ra_chain *next;
@@ -236,7 +220,7 @@ extern struct ipv6_txoptions *fl6_merge_options(struct ipv6_txoptions * opt_spac
struct ipv6_txoptions * fopt);
extern void fl6_free_socklist(struct sock *sk);
extern int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen);
-extern void ip6_flowlabel_init(void);
+extern int ip6_flowlabel_init(void);
extern void ip6_flowlabel_cleanup(void);
static inline void fl6_sock_release(struct ip6_flowlabel *fl)
@@ -261,8 +245,8 @@ struct ipv6_txoptions *ipv6_fixup_options(struct ipv6_txoptions *opt_space,
extern int ipv6_opt_accepted(struct sock *sk, struct sk_buff *skb);
-int ip6_frag_nqueues(void);
-int ip6_frag_mem(void);
+int ip6_frag_nqueues(struct net *net);
+int ip6_frag_mem(struct net *net);
#define IPV6_FRAG_TIMEOUT (60*HZ) /* 60 seconds */
@@ -509,6 +493,9 @@ extern int ip6_forward(struct sk_buff *skb);
extern int ip6_input(struct sk_buff *skb);
extern int ip6_mc_input(struct sk_buff *skb);
+extern int __ip6_local_out(struct sk_buff *skb);
+extern int ip6_local_out(struct sk_buff *skb);
+
/*
* Extension header (options) processing
*/
@@ -559,7 +546,7 @@ extern int compat_ipv6_getsockopt(struct sock *sk,
char __user *optval,
int __user *optlen);
-extern void ipv6_packet_init(void);
+extern int ipv6_packet_init(void);
extern void ipv6_packet_cleanup(void);
@@ -585,9 +572,6 @@ extern int inet6_hash_connect(struct inet_timewait_death_row *death_row,
/*
* reassembly.c
*/
-struct inet_frags_ctl;
-extern struct inet_frags_ctl ip6_frags_ctl;
-
extern const struct proto_ops inet6_stream_ops;
extern const struct proto_ops inet6_dgram_ops;
@@ -602,6 +586,9 @@ extern int ip6_mc_msfget(struct sock *sk, struct group_filter *gsf,
int __user *optlen);
#ifdef CONFIG_PROC_FS
+extern struct ctl_table *ipv6_icmp_sysctl_init(struct net *net);
+extern struct ctl_table *ipv6_route_sysctl_init(struct net *net);
+
extern int ac6_proc_init(void);
extern void ac6_proc_exit(void);
extern int raw6_proc_init(void);
@@ -631,10 +618,10 @@ static inline int snmp6_unregister_dev(struct inet6_dev *idev)
#endif
#ifdef CONFIG_SYSCTL
-extern ctl_table ipv6_route_table[];
-extern ctl_table ipv6_icmp_table[];
+extern ctl_table ipv6_route_table_template[];
+extern ctl_table ipv6_icmp_table_template[];
-extern void ipv6_sysctl_register(void);
+extern int ipv6_sysctl_register(void);
extern void ipv6_sysctl_unregister(void);
#endif
diff --git a/include/net/irda/irda_device.h b/include/net/irda/irda_device.h
index bca19ca7bdd..f70e9b39eba 100644
--- a/include/net/irda/irda_device.h
+++ b/include/net/irda/irda_device.h
@@ -228,21 +228,8 @@ static inline int irda_device_txqueue_empty(const struct net_device *dev)
int irda_device_set_raw_mode(struct net_device* self, int status);
struct net_device *alloc_irdadev(int sizeof_priv);
-/* Dongle interface */
-void irda_device_unregister_dongle(struct dongle_reg *dongle);
-int irda_device_register_dongle(struct dongle_reg *dongle);
-dongle_t *irda_device_dongle_init(struct net_device *dev, int type);
-int irda_device_dongle_cleanup(dongle_t *dongle);
-
void irda_setup_dma(int channel, dma_addr_t buffer, int count, int mode);
-void irda_task_delete(struct irda_task *task);
-struct irda_task *irda_task_execute(void *instance,
- IRDA_TASK_CALLBACK function,
- IRDA_TASK_CALLBACK finished,
- struct irda_task *parent, void *param);
-void irda_task_next_state(struct irda_task *task, IRDA_TASK_STATE state);
-
/*
* Function irda_get_mtt (skb)
*
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 17b60391fcd..9083bafb63c 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -139,17 +139,54 @@ enum ieee80211_phymode {
};
/**
+ * struct ieee80211_ht_info - describing STA's HT capabilities
+ *
+ * This structure describes most essential parameters needed
+ * to describe 802.11n HT capabilities for an STA.
+ *
+ * @ht_supported: is HT supported by STA, 0: no, 1: yes
+ * @cap: HT capabilities map as described in 802.11n spec
+ * @ampdu_factor: Maximum A-MPDU length factor
+ * @ampdu_density: Minimum A-MPDU spacing
+ * @supp_mcs_set: Supported MCS set as described in 802.11n spec
+ */
+struct ieee80211_ht_info {
+ u8 ht_supported;
+ u16 cap; /* use IEEE80211_HT_CAP_ */
+ u8 ampdu_factor;
+ u8 ampdu_density;
+ u8 supp_mcs_set[16];
+};
+
+/**
+ * struct ieee80211_ht_bss_info - describing BSS's HT characteristics
+ *
+ * This structure describes most essential parameters needed
+ * to describe 802.11n HT characteristics in a BSS
+ *
+ * @primary_channel: channel number of primery channel
+ * @bss_cap: 802.11n's general BSS capabilities (e.g. channel width)
+ * @bss_op_mode: 802.11n's BSS operation modes (e.g. HT protection)
+ */
+struct ieee80211_ht_bss_info {
+ u8 primary_channel;
+ u8 bss_cap; /* use IEEE80211_HT_IE_CHA_ */
+ u8 bss_op_mode; /* use IEEE80211_HT_IE_ */
+};
+
+/**
* struct ieee80211_hw_mode - PHY mode definition
*
* This structure describes the capabilities supported by the device
* in a single PHY mode.
*
+ * @list: internal
+ * @channels: pointer to array of supported channels
+ * @rates: pointer to array of supported bitrates
* @mode: the PHY mode for this definition
* @num_channels: number of supported channels
- * @channels: pointer to array of supported channels
* @num_rates: number of supported bitrates
- * @rates: pointer to array of supported bitrates
- * @list: internal
+ * @ht_info: PHY's 802.11n HT abilities for this mode
*/
struct ieee80211_hw_mode {
struct list_head list;
@@ -158,6 +195,7 @@ struct ieee80211_hw_mode {
enum ieee80211_phymode mode;
int num_channels;
int num_rates;
+ struct ieee80211_ht_info ht_info;
};
/**
@@ -237,11 +275,49 @@ struct ieee80211_low_level_stats {
unsigned int dot11RTSSuccessCount;
};
+/**
+ * enum ieee80211_bss_change - BSS change notification flags
+ *
+ * These flags are used with the bss_info_changed() callback
+ * to indicate which BSS parameter changed.
+ *
+ * @BSS_CHANGED_ASSOC: association status changed (associated/disassociated),
+ * also implies a change in the AID.
+ * @BSS_CHANGED_ERP_CTS_PROT: CTS protection changed
+ * @BSS_CHANGED_ERP_PREAMBLE: preamble changed
+ */
+enum ieee80211_bss_change {
+ BSS_CHANGED_ASSOC = 1<<0,
+ BSS_CHANGED_ERP_CTS_PROT = 1<<1,
+ BSS_CHANGED_ERP_PREAMBLE = 1<<2,
+};
+
+/**
+ * struct ieee80211_bss_conf - holds the BSS's changing parameters
+ *
+ * This structure keeps information about a BSS (and an association
+ * to that BSS) that can change during the lifetime of the BSS.
+ *
+ * @assoc: association status
+ * @aid: association ID number, valid only when @assoc is true
+ * @use_cts_prot: use CTS protection
+ * @use_short_preamble: use 802.11b short preamble
+ */
+struct ieee80211_bss_conf {
+ /* association related data */
+ bool assoc;
+ u16 aid;
+ /* erp related data */
+ bool use_cts_prot;
+ bool use_short_preamble;
+};
+
/* Transmit control fields. This data structure is passed to low-level driver
* with each TX frame. The low-level driver is responsible for configuring
* the hardware to use given values (depending on what is supported). */
struct ieee80211_tx_control {
+ struct ieee80211_vif *vif;
int tx_rate; /* Transmit rate, given as the hw specific value for the
* rate (from struct ieee80211_rate) */
int rts_cts_rate; /* Transmit rate for RTS/CTS frame, given as the hw
@@ -269,6 +345,9 @@ struct ieee80211_tx_control {
* using the through
* set_retry_limit configured
* long retry value */
+#define IEEE80211_TXCTL_EAPOL_FRAME (1<<11) /* internal to mac80211 */
+#define IEEE80211_TXCTL_SEND_AFTER_DTIM (1<<12) /* send this frame after DTIM
+ * beacon */
u32 flags; /* tx control flags defined
* above */
u8 key_idx; /* keyidx from hw->set_key(), undefined if
@@ -291,7 +370,6 @@ struct ieee80211_tx_control {
* packet dropping when probing higher rates, if hw
* supports multiple retry rates. -1 = not used */
int type; /* internal */
- int ifindex; /* internal */
};
@@ -312,6 +390,8 @@ struct ieee80211_tx_control {
* the frame.
* @RX_FLAG_FAILED_PLCP_CRC: Set this flag if the PCLP check failed on
* the frame.
+ * @RX_FLAG_TSFT: The timestamp passed in the RX status (@mactime field)
+ * is valid.
*/
enum mac80211_rx_flags {
RX_FLAG_MMIC_ERROR = 1<<0,
@@ -321,6 +401,7 @@ enum mac80211_rx_flags {
RX_FLAG_IV_STRIPPED = 1<<4,
RX_FLAG_FAILED_FCS_CRC = 1<<5,
RX_FLAG_FAILED_PLCP_CRC = 1<<6,
+ RX_FLAG_TSFT = 1<<7,
};
/**
@@ -406,11 +487,12 @@ struct ieee80211_tx_status {
*
* @IEEE80211_CONF_SHORT_SLOT_TIME: use 802.11g short slot time
* @IEEE80211_CONF_RADIOTAP: add radiotap header at receive time (if supported)
- *
+ * @IEEE80211_CONF_SUPPORT_HT_MODE: use 802.11n HT capabilities (if supported)
*/
enum ieee80211_conf_flags {
- IEEE80211_CONF_SHORT_SLOT_TIME = 1<<0,
- IEEE80211_CONF_RADIOTAP = 1<<1,
+ IEEE80211_CONF_SHORT_SLOT_TIME = (1<<0),
+ IEEE80211_CONF_RADIOTAP = (1<<1),
+ IEEE80211_CONF_SUPPORT_HT_MODE = (1<<2),
};
/**
@@ -434,6 +516,8 @@ enum ieee80211_conf_flags {
* @antenna_sel_tx: transmit antenna selection, 0: default/diversity,
* 1/2: antenna 0/1
* @antenna_sel_rx: receive antenna selection, like @antenna_sel_tx
+ * @ht_conf: describes current self configuration of 802.11n HT capabilies
+ * @ht_bss_conf: describes current BSS configuration of 802.11n HT parameters
*/
struct ieee80211_conf {
int channel; /* IEEE 802.11 channel number */
@@ -452,6 +536,9 @@ struct ieee80211_conf {
u8 antenna_max;
u8 antenna_sel_tx;
u8 antenna_sel_rx;
+
+ struct ieee80211_ht_info ht_conf;
+ struct ieee80211_ht_bss_info ht_bss_conf;
};
/**
@@ -480,13 +567,27 @@ enum ieee80211_if_types {
};
/**
+ * struct ieee80211_vif - per-interface data
+ *
+ * Data in this structure is continually present for driver
+ * use during the life of a virtual interface.
+ *
+ * @type: type of this virtual interface
+ * @drv_priv: data area for driver use, will always be aligned to
+ * sizeof(void *).
+ */
+struct ieee80211_vif {
+ enum ieee80211_if_types type;
+ /* must be last */
+ u8 drv_priv[0] __attribute__((__aligned__(sizeof(void *))));
+};
+
+/**
* struct ieee80211_if_init_conf - initial configuration of an interface
*
- * @if_id: internal interface ID. This number has no particular meaning to
- * drivers and the only allowed usage is to pass it to
- * ieee80211_beacon_get() and ieee80211_get_buffered_bc() functions.
- * This field is not valid for monitor interfaces
- * (interfaces of %IEEE80211_IF_TYPE_MNTR type).
+ * @vif: pointer to a driver-use per-interface structure. The pointer
+ * itself is also used for various functions including
+ * ieee80211_beacon_get() and ieee80211_get_buffered_bc().
* @type: one of &enum ieee80211_if_types constants. Determines the type of
* added/removed interface.
* @mac_addr: pointer to MAC address of the interface. This pointer is valid
@@ -503,8 +604,8 @@ enum ieee80211_if_types {
* in pure monitor mode.
*/
struct ieee80211_if_init_conf {
- int if_id;
enum ieee80211_if_types type;
+ struct ieee80211_vif *vif;
void *mac_addr;
};
@@ -597,9 +698,6 @@ struct ieee80211_key_conf {
u8 key[0];
};
-#define IEEE80211_SEQ_COUNTER_RX 0
-#define IEEE80211_SEQ_COUNTER_TX 1
-
/**
* enum set_key_cmd - key command
*
@@ -710,6 +808,9 @@ enum ieee80211_hw_flags {
* @rate_control_algorithm: rate control algorithm for this hardware.
* If unset (NULL), the default algorithm will be used. Must be
* set before calling ieee80211_register_hw().
+ *
+ * @vif_data_size: size (in bytes) of the drv_priv data area
+ * within &struct ieee80211_vif.
*/
struct ieee80211_hw {
struct ieee80211_conf conf;
@@ -720,6 +821,7 @@ struct ieee80211_hw {
u32 flags;
unsigned int extra_tx_headroom;
int channel_change_time;
+ int vif_data_size;
u8 queues;
s8 max_rssi;
s8 max_signal;
@@ -859,19 +961,18 @@ enum ieee80211_filter_flags {
};
/**
- * enum ieee80211_erp_change_flags - erp change flags
+ * enum ieee80211_ampdu_mlme_action - A-MPDU actions
*
- * These flags are used with the erp_ie_changed() callback in
- * &struct ieee80211_ops to indicate which parameter(s) changed.
- * @IEEE80211_ERP_CHANGE_PROTECTION: protection changed
- * @IEEE80211_ERP_CHANGE_PREAMBLE: barker preamble mode changed
+ * These flags are used with the ampdu_action() callback in
+ * &struct ieee80211_ops to indicate which action is needed.
+ * @IEEE80211_AMPDU_RX_START: start Rx aggregation
+ * @IEEE80211_AMPDU_RX_STOP: stop Rx aggregation
*/
-enum ieee80211_erp_change_flags {
- IEEE80211_ERP_CHANGE_PROTECTION = 1<<0,
- IEEE80211_ERP_CHANGE_PREAMBLE = 1<<1,
+enum ieee80211_ampdu_mlme_action {
+ IEEE80211_AMPDU_RX_START,
+ IEEE80211_AMPDU_RX_STOP,
};
-
/**
* struct ieee80211_ops - callbacks from mac80211 to the driver
*
@@ -927,6 +1028,14 @@ enum ieee80211_erp_change_flags {
* @config_interface: Handler for configuration requests related to interfaces
* (e.g. BSSID changes.)
*
+ * @bss_info_changed: Handler for configuration requests related to BSS
+ * parameters that may vary during BSS's lifespan, and may affect low
+ * level driver (e.g. assoc/disassoc status, erp parameters).
+ * This function should not be used if no BSS has been set, unless
+ * for association indication. The @changed parameter indicates which
+ * of the bss parameters has changed when a call is made. This callback
+ * has to be atomic.
+ *
* @configure_filter: Configure the device's RX filter.
* See the section "Frame filtering" for more information.
* This callback must be implemented and atomic.
@@ -946,9 +1055,9 @@ enum ieee80211_erp_change_flags {
*
* @get_stats: return low-level statistics
*
- * @get_sequence_counter: For devices that have internal sequence counters this
- * callback allows mac80211 to access the current value of a counter.
- * This callback seems not well-defined, tell us if you need it.
+ * @get_tkip_seq: If your device implements TKIP encryption in hardware this
+ * callback should be provided to read the TKIP transmit IVs (both IV32
+ * and IV16) for the given key from hardware.
*
* @set_rts_threshold: Configuration of RTS threshold (if device needs it)
*
@@ -961,8 +1070,6 @@ enum ieee80211_erp_change_flags {
* @sta_notify: Notifies low level driver about addition or removal
* of assocaited station or AP.
*
- * @erp_ie_changed: Handle ERP IE change notifications. Must be atomic.
- *
* @conf_tx: Configure TX queue parameters (EDCF (aifs, cw_min, cw_max),
* bursting) for a hardware TX queue. The @queue parameter uses the
* %IEEE80211_TX_QUEUE_* constants. Must be atomic.
@@ -997,6 +1104,14 @@ enum ieee80211_erp_change_flags {
* @tx_last_beacon: Determine whether the last IBSS beacon was sent by us.
* This is needed only for IBSS mode and the result of this function is
* used to determine whether to reply to Probe Requests.
+ *
+ * @conf_ht: Configures low level driver with 802.11n HT data. Must be atomic.
+ *
+ * @ampdu_action: Perform a certain A-MPDU action
+ * The RA/TID combination determines the destination and TID we want
+ * the ampdu action to be performed for. The action is defined through
+ * ieee80211_ampdu_mlme_action. Starting sequence number (@ssn)
+ * is the first frame we expect to perform the action on.
*/
struct ieee80211_ops {
int (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb,
@@ -1009,7 +1124,12 @@ struct ieee80211_ops {
struct ieee80211_if_init_conf *conf);
int (*config)(struct ieee80211_hw *hw, struct ieee80211_conf *conf);
int (*config_interface)(struct ieee80211_hw *hw,
- int if_id, struct ieee80211_if_conf *conf);
+ struct ieee80211_vif *vif,
+ struct ieee80211_if_conf *conf);
+ void (*bss_info_changed)(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *info,
+ u32 changed);
void (*configure_filter)(struct ieee80211_hw *hw,
unsigned int changed_flags,
unsigned int *total_flags,
@@ -1021,17 +1141,14 @@ struct ieee80211_ops {
int (*hw_scan)(struct ieee80211_hw *hw, u8 *ssid, size_t len);
int (*get_stats)(struct ieee80211_hw *hw,
struct ieee80211_low_level_stats *stats);
- int (*get_sequence_counter)(struct ieee80211_hw *hw,
- u8* addr, u8 keyidx, u8 txrx,
- u32* iv32, u16* iv16);
+ void (*get_tkip_seq)(struct ieee80211_hw *hw, u8 hw_key_idx,
+ u32 *iv32, u16 *iv16);
int (*set_rts_threshold)(struct ieee80211_hw *hw, u32 value);
int (*set_frag_threshold)(struct ieee80211_hw *hw, u32 value);
int (*set_retry_limit)(struct ieee80211_hw *hw,
u32 short_retry, u32 long_retr);
- void (*sta_notify)(struct ieee80211_hw *hw, int if_id,
+ void (*sta_notify)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
enum sta_notify_cmd, const u8 *addr);
- void (*erp_ie_changed)(struct ieee80211_hw *hw, u8 changes,
- int cts_protection, int preamble);
int (*conf_tx)(struct ieee80211_hw *hw, int queue,
const struct ieee80211_tx_queue_params *params);
int (*get_tx_stats)(struct ieee80211_hw *hw,
@@ -1042,6 +1159,10 @@ struct ieee80211_ops {
struct sk_buff *skb,
struct ieee80211_tx_control *control);
int (*tx_last_beacon)(struct ieee80211_hw *hw);
+ int (*conf_ht)(struct ieee80211_hw *hw, struct ieee80211_conf *conf);
+ int (*ampdu_action)(struct ieee80211_hw *hw,
+ enum ieee80211_ampdu_mlme_action action,
+ const u8 *ra, u16 tid, u16 ssn);
};
/**
@@ -1073,6 +1194,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw);
extern char *__ieee80211_get_tx_led_name(struct ieee80211_hw *hw);
extern char *__ieee80211_get_rx_led_name(struct ieee80211_hw *hw);
extern char *__ieee80211_get_assoc_led_name(struct ieee80211_hw *hw);
+extern char *__ieee80211_get_radio_led_name(struct ieee80211_hw *hw);
#endif
/**
* ieee80211_get_tx_led_name - get name of TX LED
@@ -1112,6 +1234,16 @@ static inline char *ieee80211_get_rx_led_name(struct ieee80211_hw *hw)
#endif
}
+/**
+ * ieee80211_get_assoc_led_name - get name of association LED
+ *
+ * mac80211 creates a association LED trigger for each wireless hardware
+ * that can be used to drive LEDs if your driver registers a LED device.
+ * This function returns the name (or %NULL if not configured for LEDs)
+ * of the trigger so you can automatically link the LED device.
+ *
+ * @hw: the hardware to get the LED trigger name for
+ */
static inline char *ieee80211_get_assoc_led_name(struct ieee80211_hw *hw)
{
#ifdef CONFIG_MAC80211_LEDS
@@ -1121,6 +1253,24 @@ static inline char *ieee80211_get_assoc_led_name(struct ieee80211_hw *hw)
#endif
}
+/**
+ * ieee80211_get_radio_led_name - get name of radio LED
+ *
+ * mac80211 creates a radio change LED trigger for each wireless hardware
+ * that can be used to drive LEDs if your driver registers a LED device.
+ * This function returns the name (or %NULL if not configured for LEDs)
+ * of the trigger so you can automatically link the LED device.
+ *
+ * @hw: the hardware to get the LED trigger name for
+ */
+static inline char *ieee80211_get_radio_led_name(struct ieee80211_hw *hw)
+{
+#ifdef CONFIG_MAC80211_LEDS
+ return __ieee80211_get_radio_led_name(hw);
+#else
+ return NULL;
+#endif
+}
/* Register a new hardware PHYMODE capability to the stack. */
int ieee80211_register_hwmode(struct ieee80211_hw *hw,
@@ -1210,7 +1360,7 @@ void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw,
/**
* ieee80211_beacon_get - beacon generation function
* @hw: pointer obtained from ieee80211_alloc_hw().
- * @if_id: interface ID from &struct ieee80211_if_init_conf.
+ * @vif: &struct ieee80211_vif pointer from &struct ieee80211_if_init_conf.
* @control: will be filled with information needed to send this beacon.
*
* If the beacon frames are generated by the host system (i.e., not in
@@ -1221,13 +1371,13 @@ void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw,
* is responsible of freeing it.
*/
struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
- int if_id,
+ struct ieee80211_vif *vif,
struct ieee80211_tx_control *control);
/**
* ieee80211_rts_get - RTS frame generation function
* @hw: pointer obtained from ieee80211_alloc_hw().
- * @if_id: interface ID from &struct ieee80211_if_init_conf.
+ * @vif: &struct ieee80211_vif pointer from &struct ieee80211_if_init_conf.
* @frame: pointer to the frame that is going to be protected by the RTS.
* @frame_len: the frame length (in octets).
* @frame_txctl: &struct ieee80211_tx_control of the frame.
@@ -1238,7 +1388,7 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
* the next RTS frame from the 802.11 code. The low-level is responsible
* for calling this function before and RTS frame is needed.
*/
-void ieee80211_rts_get(struct ieee80211_hw *hw, int if_id,
+void ieee80211_rts_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
const void *frame, size_t frame_len,
const struct ieee80211_tx_control *frame_txctl,
struct ieee80211_rts *rts);
@@ -1246,7 +1396,7 @@ void ieee80211_rts_get(struct ieee80211_hw *hw, int if_id,
/**
* ieee80211_rts_duration - Get the duration field for an RTS frame
* @hw: pointer obtained from ieee80211_alloc_hw().
- * @if_id: interface ID from &struct ieee80211_if_init_conf.
+ * @vif: &struct ieee80211_vif pointer from &struct ieee80211_if_init_conf.
* @frame_len: the length of the frame that is going to be protected by the RTS.
* @frame_txctl: &struct ieee80211_tx_control of the frame.
*
@@ -1254,14 +1404,14 @@ void ieee80211_rts_get(struct ieee80211_hw *hw, int if_id,
* the duration field, the low-level driver uses this function to receive
* the duration field value in little-endian byteorder.
*/
-__le16 ieee80211_rts_duration(struct ieee80211_hw *hw, int if_id,
- size_t frame_len,
+__le16 ieee80211_rts_duration(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif, size_t frame_len,
const struct ieee80211_tx_control *frame_txctl);
/**
* ieee80211_ctstoself_get - CTS-to-self frame generation function
* @hw: pointer obtained from ieee80211_alloc_hw().
- * @if_id: interface ID from &struct ieee80211_if_init_conf.
+ * @vif: &struct ieee80211_vif pointer from &struct ieee80211_if_init_conf.
* @frame: pointer to the frame that is going to be protected by the CTS-to-self.
* @frame_len: the frame length (in octets).
* @frame_txctl: &struct ieee80211_tx_control of the frame.
@@ -1272,7 +1422,8 @@ __le16 ieee80211_rts_duration(struct ieee80211_hw *hw, int if_id,
* the next CTS-to-self frame from the 802.11 code. The low-level is responsible
* for calling this function before and CTS-to-self frame is needed.
*/
-void ieee80211_ctstoself_get(struct ieee80211_hw *hw, int if_id,
+void ieee80211_ctstoself_get(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
const void *frame, size_t frame_len,
const struct ieee80211_tx_control *frame_txctl,
struct ieee80211_cts *cts);
@@ -1280,7 +1431,7 @@ void ieee80211_ctstoself_get(struct ieee80211_hw *hw, int if_id,
/**
* ieee80211_ctstoself_duration - Get the duration field for a CTS-to-self frame
* @hw: pointer obtained from ieee80211_alloc_hw().
- * @if_id: interface ID from &struct ieee80211_if_init_conf.
+ * @vif: &struct ieee80211_vif pointer from &struct ieee80211_if_init_conf.
* @frame_len: the length of the frame that is going to be protected by the CTS-to-self.
* @frame_txctl: &struct ieee80211_tx_control of the frame.
*
@@ -1288,28 +1439,30 @@ void ieee80211_ctstoself_get(struct ieee80211_hw *hw, int if_id,
* the duration field, the low-level driver uses this function to receive
* the duration field value in little-endian byteorder.
*/
-__le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw, int if_id,
+__le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
size_t frame_len,
const struct ieee80211_tx_control *frame_txctl);
/**
* ieee80211_generic_frame_duration - Calculate the duration field for a frame
* @hw: pointer obtained from ieee80211_alloc_hw().
- * @if_id: interface ID from &struct ieee80211_if_init_conf.
+ * @vif: &struct ieee80211_vif pointer from &struct ieee80211_if_init_conf.
* @frame_len: the length of the frame.
* @rate: the rate (in 100kbps) at which the frame is going to be transmitted.
*
* Calculate the duration field of some generic frame, given its
* length and transmission rate (in 100kbps).
*/
-__le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw, int if_id,
+__le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
size_t frame_len,
int rate);
/**
* ieee80211_get_buffered_bc - accessing buffered broadcast and multicast frames
* @hw: pointer as obtained from ieee80211_alloc_hw().
- * @if_id: interface ID from &struct ieee80211_if_init_conf.
+ * @vif: &struct ieee80211_vif pointer from &struct ieee80211_if_init_conf.
* @control: will be filled with information needed to send returned frame.
*
* Function for accessing buffered broadcast and multicast frames. If
@@ -1328,7 +1481,7 @@ __le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw, int if_id,
* use common code for all beacons.
*/
struct sk_buff *
-ieee80211_get_buffered_bc(struct ieee80211_hw *hw, int if_id,
+ieee80211_get_buffered_bc(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct ieee80211_tx_control *control);
/**
@@ -1406,4 +1559,19 @@ void ieee80211_wake_queues(struct ieee80211_hw *hw);
*/
void ieee80211_scan_completed(struct ieee80211_hw *hw);
+/**
+ * ieee80211_iterate_active_interfaces - iterate active interfaces
+ *
+ * This function iterates over the interfaces associated with a given
+ * hardware that are currently active and calls the callback for them.
+ *
+ * @hw: the hardware struct of which the interfaces should be iterated over
+ * @iterator: the iterator function to call, cannot sleep
+ * @data: first argument of the iterator function
+ */
+void ieee80211_iterate_active_interfaces(struct ieee80211_hw *hw,
+ void (*iterator)(void *data, u8 *mac,
+ struct ieee80211_vif *vif),
+ void *data);
+
#endif /* MAC80211_H */
diff --git a/include/net/neighbour.h b/include/net/neighbour.h
index a4f26187fc1..ebbfb509822 100644
--- a/include/net/neighbour.h
+++ b/include/net/neighbour.h
@@ -26,6 +26,10 @@
#include <linux/sysctl.h>
#include <net/rtnetlink.h>
+/*
+ * NUD stands for "neighbor unreachability detection"
+ */
+
#define NUD_IN_TIMER (NUD_INCOMPLETE|NUD_REACHABLE|NUD_DELAY|NUD_PROBE)
#define NUD_VALID (NUD_PERMANENT|NUD_NOARP|NUD_REACHABLE|NUD_PROBE|NUD_STALE|NUD_DELAY)
#define NUD_CONNECTED (NUD_PERMANENT|NUD_NOARP|NUD_REACHABLE)
@@ -34,6 +38,7 @@ struct neighbour;
struct neigh_parms
{
+ struct net *net;
struct net_device *dev;
struct neigh_parms *next;
int (*neigh_setup)(struct neighbour *);
@@ -126,7 +131,8 @@ struct neigh_ops
struct pneigh_entry
{
struct pneigh_entry *next;
- struct net_device *dev;
+ struct net *net;
+ struct net_device *dev;
u8 flags;
u8 key[0];
};
@@ -187,6 +193,7 @@ extern struct neighbour * neigh_lookup(struct neigh_table *tbl,
const void *pkey,
struct net_device *dev);
extern struct neighbour * neigh_lookup_nodev(struct neigh_table *tbl,
+ struct net *net,
const void *pkey);
extern struct neighbour * neigh_create(struct neigh_table *tbl,
const void *pkey,
@@ -206,13 +213,12 @@ extern struct neighbour *neigh_event_ns(struct neigh_table *tbl,
extern struct neigh_parms *neigh_parms_alloc(struct net_device *dev, struct neigh_table *tbl);
extern void neigh_parms_release(struct neigh_table *tbl, struct neigh_parms *parms);
-extern void neigh_parms_destroy(struct neigh_parms *parms);
extern unsigned long neigh_rand_reach_time(unsigned long base);
extern void pneigh_enqueue(struct neigh_table *tbl, struct neigh_parms *p,
struct sk_buff *skb);
-extern struct pneigh_entry *pneigh_lookup(struct neigh_table *tbl, const void *key, struct net_device *dev, int creat);
-extern int pneigh_delete(struct neigh_table *tbl, const void *key, struct net_device *dev);
+extern struct pneigh_entry *pneigh_lookup(struct neigh_table *tbl, struct net *net, const void *key, struct net_device *dev, int creat);
+extern int pneigh_delete(struct neigh_table *tbl, struct net *net, const void *key, struct net_device *dev);
extern void neigh_app_ns(struct neighbour *n);
extern void neigh_for_each(struct neigh_table *tbl, void (*cb)(struct neighbour *, void *), void *cookie);
@@ -220,6 +226,7 @@ extern void __neigh_for_each_release(struct neigh_table *tbl, int (*cb)(struct n
extern void pneigh_for_each(struct neigh_table *tbl, void (*cb)(struct pneigh_entry *));
struct neigh_seq_state {
+ struct seq_net_private p;
struct neigh_table *tbl;
void *(*neigh_sub_iter)(struct neigh_seq_state *state,
struct neighbour *n, loff_t *pos);
@@ -246,12 +253,6 @@ static inline void __neigh_parms_put(struct neigh_parms *parms)
atomic_dec(&parms->refcnt);
}
-static inline void neigh_parms_put(struct neigh_parms *parms)
-{
- if (atomic_dec_and_test(&parms->refcnt))
- neigh_parms_destroy(parms);
-}
-
static inline struct neigh_parms *neigh_parms_clone(struct neigh_parms *parms)
{
atomic_inc(&parms->refcnt);
@@ -288,10 +289,6 @@ static inline int neigh_is_connected(struct neighbour *neigh)
return neigh->nud_state&NUD_CONNECTED;
}
-static inline int neigh_is_valid(struct neighbour *neigh)
-{
- return neigh->nud_state&NUD_VALID;
-}
static inline int neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)
{
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
index 5dd6d90b37e..b8c1d60ba9e 100644
--- a/include/net/net_namespace.h
+++ b/include/net/net_namespace.h
@@ -8,8 +8,16 @@
#include <linux/workqueue.h>
#include <linux/list.h>
+#include <net/netns/unix.h>
+#include <net/netns/packet.h>
+#include <net/netns/ipv4.h>
+#include <net/netns/ipv6.h>
+
struct proc_dir_entry;
struct net_device;
+struct sock;
+struct ctl_table_header;
+
struct net {
atomic_t count; /* To decided when the network
* namespace should be freed.
@@ -24,11 +32,30 @@ struct net {
struct proc_dir_entry *proc_net_stat;
struct proc_dir_entry *proc_net_root;
+ struct list_head sysctl_table_headers;
+
struct net_device *loopback_dev; /* The loopback */
struct list_head dev_base_head;
struct hlist_head *dev_name_head;
struct hlist_head *dev_index_head;
+
+ /* core fib_rules */
+ struct list_head rules_ops;
+ spinlock_t rules_mod_lock;
+
+ struct sock *rtnl; /* rtnetlink socket */
+
+ /* core sysctls */
+ struct ctl_table_header *sysctl_core_hdr;
+ int sysctl_somaxconn;
+
+ struct netns_packet packet;
+ struct netns_unix unx;
+ struct netns_ipv4 ipv4;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+ struct netns_ipv6 ipv6;
+#endif
};
#ifdef CONFIG_NET
@@ -137,4 +164,11 @@ extern void unregister_pernet_subsys(struct pernet_operations *);
extern int register_pernet_device(struct pernet_operations *);
extern void unregister_pernet_device(struct pernet_operations *);
+struct ctl_path;
+struct ctl_table;
+struct ctl_table_header;
+extern struct ctl_table_header *register_net_sysctl_table(struct net *net,
+ const struct ctl_path *path, struct ctl_table *table);
+extern void unregister_net_sysctl_table(struct ctl_table_header *header);
+
#endif /* __NET_NET_NAMESPACE_H */
diff --git a/include/net/netevent.h b/include/net/netevent.h
index e5d21624142..e82b7bab3ff 100644
--- a/include/net/netevent.h
+++ b/include/net/netevent.h
@@ -12,7 +12,7 @@
*/
#ifdef __KERNEL__
-#include <net/dst.h>
+struct dst_entry;
struct netevent_redirect {
struct dst_entry *old;
diff --git a/include/net/netfilter/ipv6/nf_conntrack_ipv6.h b/include/net/netfilter/ipv6/nf_conntrack_ipv6.h
index f703533fb4d..abc55ad75c2 100644
--- a/include/net/netfilter/ipv6/nf_conntrack_ipv6.h
+++ b/include/net/netfilter/ipv6/nf_conntrack_ipv6.h
@@ -16,6 +16,8 @@ extern void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb,
int (*okfn)(struct sk_buff *));
struct inet_frags_ctl;
-extern struct inet_frags_ctl nf_frags_ctl;
+
+#include <linux/sysctl.h>
+extern struct ctl_table nf_ct_ipv6_sysctl_table[];
#endif /* _NF_CONNTRACK_IPV6_H*/
diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h
index 4ac5ab187c2..857d8995179 100644
--- a/include/net/netfilter/nf_conntrack.h
+++ b/include/net/netfilter/nf_conntrack.h
@@ -223,8 +223,6 @@ extern void nf_conntrack_tcp_update(struct sk_buff *skb,
/* Fake conntrack entry for untracked connections */
extern struct nf_conn nf_conntrack_untracked;
-extern int nf_ct_no_defrag;
-
/* Iterate over all conntracks: if iter returns true, it's deleted. */
extern void
nf_ct_iterate_cleanup(int (*iter)(struct nf_conn *i, void *data), void *data);
@@ -264,10 +262,5 @@ do { \
local_bh_enable(); \
} while (0)
-extern int
-nf_conntrack_register_cache(u_int32_t features, const char *name, size_t size);
-extern void
-nf_conntrack_unregister_cache(u_int32_t features);
-
#endif /* __KERNEL__ */
#endif /* _NF_CONNTRACK_H */
diff --git a/include/net/netfilter/nf_conntrack_core.h b/include/net/netfilter/nf_conntrack_core.h
index a532e7b5ed6..7ad0828f05c 100644
--- a/include/net/netfilter/nf_conntrack_core.h
+++ b/include/net/netfilter/nf_conntrack_core.h
@@ -30,16 +30,6 @@ extern void nf_conntrack_cleanup(void);
extern int nf_conntrack_proto_init(void);
extern void nf_conntrack_proto_fini(void);
-extern int nf_conntrack_helper_init(void);
-extern void nf_conntrack_helper_fini(void);
-
-struct nf_conntrack_l3proto;
-extern struct nf_conntrack_l3proto *nf_ct_find_l3proto(u_int16_t pf);
-/* Like above, but you already have conntrack read lock. */
-extern struct nf_conntrack_l3proto *__nf_ct_find_l3proto(u_int16_t l3proto);
-
-struct nf_conntrack_l4proto;
-
extern int
nf_ct_get_tuple(const struct sk_buff *skb,
unsigned int nhoff,
@@ -76,8 +66,6 @@ static inline int nf_conntrack_confirm(struct sk_buff *skb)
return ret;
}
-extern void __nf_conntrack_attach(struct sk_buff *nskb, struct sk_buff *skb);
-
int
print_tuple(struct seq_file *s, const struct nf_conntrack_tuple *tuple,
struct nf_conntrack_l3proto *l3proto,
diff --git a/include/net/netfilter/nf_conntrack_expect.h b/include/net/netfilter/nf_conntrack_expect.h
index b47c04f12db..6c3fd254c28 100644
--- a/include/net/netfilter/nf_conntrack_expect.h
+++ b/include/net/netfilter/nf_conntrack_expect.h
@@ -73,8 +73,8 @@ void nf_ct_unexpect_related(struct nf_conntrack_expect *exp);
nf_ct_expect_related. You will have to call put afterwards. */
struct nf_conntrack_expect *nf_ct_expect_alloc(struct nf_conn *me);
void nf_ct_expect_init(struct nf_conntrack_expect *, int,
- union nf_conntrack_address *,
- union nf_conntrack_address *,
+ union nf_inet_addr *,
+ union nf_inet_addr *,
u_int8_t, __be16 *, __be16 *);
void nf_ct_expect_put(struct nf_conntrack_expect *exp);
int nf_ct_expect_related(struct nf_conntrack_expect *expect);
diff --git a/include/net/netfilter/nf_conntrack_helper.h b/include/net/netfilter/nf_conntrack_helper.h
index d7b2d5483a7..2f3af00643c 100644
--- a/include/net/netfilter/nf_conntrack_helper.h
+++ b/include/net/netfilter/nf_conntrack_helper.h
@@ -58,4 +58,8 @@ static inline struct nf_conn_help *nfct_help(const struct nf_conn *ct)
{
return nf_ct_ext_find(ct, NF_CT_EXT_HELPER);
}
+
+extern int nf_conntrack_helper_init(void);
+extern void nf_conntrack_helper_fini(void);
+
#endif /*_NF_CONNTRACK_HELPER_H*/
diff --git a/include/net/netfilter/nf_conntrack_l3proto.h b/include/net/netfilter/nf_conntrack_l3proto.h
index 15888fc7b72..d5526bcce14 100644
--- a/include/net/netfilter/nf_conntrack_l3proto.h
+++ b/include/net/netfilter/nf_conntrack_l3proto.h
@@ -42,9 +42,6 @@ struct nf_conntrack_l3proto
int (*print_tuple)(struct seq_file *s,
const struct nf_conntrack_tuple *);
- /* Print out the private part of the conntrack. */
- int (*print_conntrack)(struct seq_file *s, const struct nf_conn *);
-
/* Returns verdict for packet, or -1 for invalid. */
int (*packet)(struct nf_conn *conntrack,
const struct sk_buff *skb,
@@ -73,7 +70,7 @@ struct nf_conntrack_l3proto
#ifdef CONFIG_SYSCTL
struct ctl_table_header *ctl_table_header;
- struct ctl_table *ctl_table_path;
+ struct ctl_path *ctl_table_path;
struct ctl_table *ctl_table;
#endif /* CONFIG_SYSCTL */
diff --git a/include/net/netfilter/nf_conntrack_tuple.h b/include/net/netfilter/nf_conntrack_tuple.h
index c48e390f4b0..45cb17cdcfd 100644
--- a/include/net/netfilter/nf_conntrack_tuple.h
+++ b/include/net/netfilter/nf_conntrack_tuple.h
@@ -10,6 +10,7 @@
#ifndef _NF_CONNTRACK_TUPLE_H
#define _NF_CONNTRACK_TUPLE_H
+#include <linux/netfilter/x_tables.h>
#include <linux/netfilter/nf_conntrack_tuple_common.h>
/* A `tuple' is a structure containing the information to uniquely
@@ -20,15 +21,7 @@
"non-manipulatable" lines, for the benefit of the NAT code.
*/
-#define NF_CT_TUPLE_L3SIZE 4
-
-/* The l3 protocol-specific manipulable parts of the tuple: always in
- network order! */
-union nf_conntrack_address {
- u_int32_t all[NF_CT_TUPLE_L3SIZE];
- __be32 ip;
- __be32 ip6[4];
-};
+#define NF_CT_TUPLE_L3SIZE ARRAY_SIZE(((union nf_inet_addr *)NULL)->all)
/* The protocol-specific manipulable parts of the tuple: always in
network order! */
@@ -57,7 +50,7 @@ union nf_conntrack_man_proto
/* The manipulable part of the tuple. */
struct nf_conntrack_man
{
- union nf_conntrack_address u3;
+ union nf_inet_addr u3;
union nf_conntrack_man_proto u;
/* Layer 3 protocol */
u_int16_t l3num;
@@ -70,7 +63,7 @@ struct nf_conntrack_tuple
/* These are the parts of the tuple which are fixed. */
struct {
- union nf_conntrack_address u3;
+ union nf_inet_addr u3;
union {
/* Add other protocols here. */
__be16 all;
@@ -103,7 +96,7 @@ struct nf_conntrack_tuple
struct nf_conntrack_tuple_mask
{
struct {
- union nf_conntrack_address u3;
+ union nf_inet_addr u3;
union nf_conntrack_man_proto u;
} src;
};
diff --git a/include/net/netfilter/nf_log.h b/include/net/netfilter/nf_log.h
new file mode 100644
index 00000000000..037e82403f9
--- /dev/null
+++ b/include/net/netfilter/nf_log.h
@@ -0,0 +1,59 @@
+#ifndef _NF_LOG_H
+#define _NF_LOG_H
+
+/* those NF_LOG_* defines and struct nf_loginfo are legacy definitios that will
+ * disappear once iptables is replaced with pkttables. Please DO NOT use them
+ * for any new code! */
+#define NF_LOG_TCPSEQ 0x01 /* Log TCP sequence numbers */
+#define NF_LOG_TCPOPT 0x02 /* Log TCP options */
+#define NF_LOG_IPOPT 0x04 /* Log IP options */
+#define NF_LOG_UID 0x08 /* Log UID owning local socket */
+#define NF_LOG_MASK 0x0f
+
+#define NF_LOG_TYPE_LOG 0x01
+#define NF_LOG_TYPE_ULOG 0x02
+
+struct nf_loginfo {
+ u_int8_t type;
+ union {
+ struct {
+ u_int32_t copy_len;
+ u_int16_t group;
+ u_int16_t qthreshold;
+ } ulog;
+ struct {
+ u_int8_t level;
+ u_int8_t logflags;
+ } log;
+ } u;
+};
+
+typedef void nf_logfn(unsigned int pf,
+ unsigned int hooknum,
+ const struct sk_buff *skb,
+ const struct net_device *in,
+ const struct net_device *out,
+ const struct nf_loginfo *li,
+ const char *prefix);
+
+struct nf_logger {
+ struct module *me;
+ nf_logfn *logfn;
+ char *name;
+};
+
+/* Function to register/unregister log function. */
+int nf_log_register(int pf, const struct nf_logger *logger);
+void nf_log_unregister(const struct nf_logger *logger);
+void nf_log_unregister_pf(int pf);
+
+/* Calls the registered backend logging function */
+void nf_log_packet(int pf,
+ unsigned int hooknum,
+ const struct sk_buff *skb,
+ const struct net_device *in,
+ const struct net_device *out,
+ const struct nf_loginfo *li,
+ const char *fmt, ...);
+
+#endif /* _NF_LOG_H */
diff --git a/include/net/netfilter/nf_nat.h b/include/net/netfilter/nf_nat.h
index 6ae52f7c9f5..9dc1039ff78 100644
--- a/include/net/netfilter/nf_nat.h
+++ b/include/net/netfilter/nf_nat.h
@@ -12,7 +12,8 @@ enum nf_nat_manip_type
};
/* SRC manip occurs POST_ROUTING or LOCAL_IN */
-#define HOOK2MANIP(hooknum) ((hooknum) != NF_IP_POST_ROUTING && (hooknum) != NF_IP_LOCAL_IN)
+#define HOOK2MANIP(hooknum) ((hooknum) != NF_INET_POST_ROUTING && \
+ (hooknum) != NF_INET_LOCAL_IN)
#define IP_NAT_RANGE_MAP_IPS 1
#define IP_NAT_RANGE_PROTO_SPECIFIED 2
@@ -79,7 +80,7 @@ struct nf_conn_nat
/* Set up the info structure to map into this range. */
extern unsigned int nf_nat_setup_info(struct nf_conn *ct,
const struct nf_nat_range *range,
- unsigned int hooknum);
+ enum nf_nat_manip_type maniptype);
/* Is this tuple already taken? (not by us)*/
extern int nf_nat_used_tuple(const struct nf_conntrack_tuple *tuple,
diff --git a/include/net/netfilter/nf_nat_protocol.h b/include/net/netfilter/nf_nat_protocol.h
index 04578bfe23e..4aa0edbb5b9 100644
--- a/include/net/netfilter/nf_nat_protocol.h
+++ b/include/net/netfilter/nf_nat_protocol.h
@@ -46,21 +46,21 @@ struct nf_nat_protocol
};
/* Protocol registration. */
-extern int nf_nat_protocol_register(struct nf_nat_protocol *proto);
-extern void nf_nat_protocol_unregister(struct nf_nat_protocol *proto);
+extern int nf_nat_protocol_register(const struct nf_nat_protocol *proto);
+extern void nf_nat_protocol_unregister(const struct nf_nat_protocol *proto);
-extern struct nf_nat_protocol *nf_nat_proto_find_get(u_int8_t protocol);
-extern void nf_nat_proto_put(struct nf_nat_protocol *proto);
+extern const struct nf_nat_protocol *nf_nat_proto_find_get(u_int8_t protocol);
+extern void nf_nat_proto_put(const struct nf_nat_protocol *proto);
/* Built-in protocols. */
-extern struct nf_nat_protocol nf_nat_protocol_tcp;
-extern struct nf_nat_protocol nf_nat_protocol_udp;
-extern struct nf_nat_protocol nf_nat_protocol_icmp;
-extern struct nf_nat_protocol nf_nat_unknown_protocol;
+extern const struct nf_nat_protocol nf_nat_protocol_tcp;
+extern const struct nf_nat_protocol nf_nat_protocol_udp;
+extern const struct nf_nat_protocol nf_nat_protocol_icmp;
+extern const struct nf_nat_protocol nf_nat_unknown_protocol;
extern int init_protocols(void) __init;
extern void cleanup_protocols(void);
-extern struct nf_nat_protocol *find_nat_proto(u_int16_t protonum);
+extern const struct nf_nat_protocol *find_nat_proto(u_int16_t protonum);
extern int nf_nat_port_range_to_nlattr(struct sk_buff *skb,
const struct nf_nat_range *range);
diff --git a/include/net/netfilter/nf_queue.h b/include/net/netfilter/nf_queue.h
new file mode 100644
index 00000000000..d030044e923
--- /dev/null
+++ b/include/net/netfilter/nf_queue.h
@@ -0,0 +1,34 @@
+#ifndef _NF_QUEUE_H
+#define _NF_QUEUE_H
+
+/* Each queued (to userspace) skbuff has one of these. */
+struct nf_queue_entry {
+ struct list_head list;
+ struct sk_buff *skb;
+ unsigned int id;
+
+ struct nf_hook_ops *elem;
+ int pf;
+ unsigned int hook;
+ struct net_device *indev;
+ struct net_device *outdev;
+ int (*okfn)(struct sk_buff *);
+};
+
+#define nf_queue_entry_reroute(x) ((void *)x + sizeof(struct nf_queue_entry))
+
+/* Packet queuing */
+struct nf_queue_handler {
+ int (*outfn)(struct nf_queue_entry *entry,
+ unsigned int queuenum);
+ char *name;
+};
+
+extern int nf_register_queue_handler(int pf,
+ const struct nf_queue_handler *qh);
+extern int nf_unregister_queue_handler(int pf,
+ const struct nf_queue_handler *qh);
+extern void nf_unregister_queue_handlers(const struct nf_queue_handler *qh);
+extern void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict);
+
+#endif /* _NF_QUEUE_H */
diff --git a/include/net/netfilter/xt_rateest.h b/include/net/netfilter/xt_rateest.h
new file mode 100644
index 00000000000..65d594dffbf
--- /dev/null
+++ b/include/net/netfilter/xt_rateest.h
@@ -0,0 +1,17 @@
+#ifndef _XT_RATEEST_H
+#define _XT_RATEEST_H
+
+struct xt_rateest {
+ struct hlist_node list;
+ char name[IFNAMSIZ];
+ unsigned int refcnt;
+ spinlock_t lock;
+ struct gnet_estimator params;
+ struct gnet_stats_rate_est rstats;
+ struct gnet_stats_basic bstats;
+};
+
+extern struct xt_rateest *xt_rateest_lookup(const char *name);
+extern void xt_rateest_put(struct xt_rateest *est);
+
+#endif /* _XT_RATEEST_H */
diff --git a/include/net/netlabel.h b/include/net/netlabel.h
index 2e5b2f6f9fa..b3213c7c530 100644
--- a/include/net/netlabel.h
+++ b/include/net/netlabel.h
@@ -67,7 +67,11 @@
* NetLabel NETLINK protocol
*/
-#define NETLBL_PROTO_VERSION 1
+/* NetLabel NETLINK protocol version
+ * 1: initial version
+ * 2: added static labels for unlabeled connections
+ */
+#define NETLBL_PROTO_VERSION 2
/* NetLabel NETLINK types/families */
#define NETLBL_NLTYPE_NONE 0
@@ -105,17 +109,49 @@ struct netlbl_dom_map;
/* Domain mapping operations */
int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info);
-/* LSM security attributes */
+/*
+ * LSM security attributes
+ */
+
+/**
+ * struct netlbl_lsm_cache - NetLabel LSM security attribute cache
+ * @refcount: atomic reference counter
+ * @free: LSM supplied function to free the cache data
+ * @data: LSM supplied cache data
+ *
+ * Description:
+ * This structure is provided for LSMs which wish to make use of the NetLabel
+ * caching mechanism to store LSM specific data/attributes in the NetLabel
+ * cache. If the LSM has to perform a lot of translation from the NetLabel
+ * security attributes into it's own internal representation then the cache
+ * mechanism can provide a way to eliminate some or all of that translation
+ * overhead on a cache hit.
+ *
+ */
struct netlbl_lsm_cache {
atomic_t refcount;
void (*free) (const void *data);
void *data;
};
-/* The catmap bitmap field MUST be a power of two in length and large
+
+/**
+ * struct netlbl_lsm_secattr_catmap - NetLabel LSM secattr category bitmap
+ * @startbit: the value of the lowest order bit in the bitmap
+ * @bitmap: the category bitmap
+ * @next: pointer to the next bitmap "node" or NULL
+ *
+ * Description:
+ * This structure is used to represent category bitmaps. Due to the large
+ * number of categories supported by most labeling protocols it is not
+ * practical to transfer a full bitmap internally so NetLabel adopts a sparse
+ * bitmap structure modeled after SELinux's ebitmap structure.
+ * The catmap bitmap field MUST be a power of two in length and large
* enough to hold at least 240 bits. Special care (i.e. check the code!)
* should be used when changing these values as the LSM implementation
* probably has functions which rely on the sizes of these types to speed
- * processing. */
+ * processing.
+ *
+ */
#define NETLBL_CATMAP_MAPTYPE u64
#define NETLBL_CATMAP_MAPCNT 4
#define NETLBL_CATMAP_MAPSIZE (sizeof(NETLBL_CATMAP_MAPTYPE) * 8)
@@ -127,22 +163,48 @@ struct netlbl_lsm_secattr_catmap {
NETLBL_CATMAP_MAPTYPE bitmap[NETLBL_CATMAP_MAPCNT];
struct netlbl_lsm_secattr_catmap *next;
};
+
+/**
+ * struct netlbl_lsm_secattr - NetLabel LSM security attributes
+ * @flags: indicate which attributes are contained in this structure
+ * @type: indicate the NLTYPE of the attributes
+ * @domain: the NetLabel LSM domain
+ * @cache: NetLabel LSM specific cache
+ * @attr.mls: MLS sensitivity label
+ * @attr.mls.cat: MLS category bitmap
+ * @attr.mls.lvl: MLS sensitivity level
+ * @attr.secid: LSM specific secid token
+ *
+ * Description:
+ * This structure is used to pass security attributes between NetLabel and the
+ * LSM modules. The flags field is used to specify which fields within the
+ * struct are valid and valid values can be created by bitwise OR'ing the
+ * NETLBL_SECATTR_* defines. The domain field is typically set by the LSM to
+ * specify domain specific configuration settings and is not usually used by
+ * NetLabel itself when returning security attributes to the LSM.
+ *
+ */
#define NETLBL_SECATTR_NONE 0x00000000
#define NETLBL_SECATTR_DOMAIN 0x00000001
#define NETLBL_SECATTR_CACHE 0x00000002
#define NETLBL_SECATTR_MLS_LVL 0x00000004
#define NETLBL_SECATTR_MLS_CAT 0x00000008
+#define NETLBL_SECATTR_SECID 0x00000010
#define NETLBL_SECATTR_CACHEABLE (NETLBL_SECATTR_MLS_LVL | \
- NETLBL_SECATTR_MLS_CAT)
+ NETLBL_SECATTR_MLS_CAT | \
+ NETLBL_SECATTR_SECID)
struct netlbl_lsm_secattr {
u32 flags;
-
+ u32 type;
char *domain;
-
- u32 mls_lvl;
- struct netlbl_lsm_secattr_catmap *mls_cat;
-
struct netlbl_lsm_cache *cache;
+ union {
+ struct {
+ struct netlbl_lsm_secattr_catmap *cat;
+ u32 lvl;
+ } mls;
+ u32 secid;
+ } attr;
};
/*
@@ -231,10 +293,7 @@ static inline void netlbl_secattr_catmap_free(
*/
static inline void netlbl_secattr_init(struct netlbl_lsm_secattr *secattr)
{
- secattr->flags = 0;
- secattr->domain = NULL;
- secattr->mls_cat = NULL;
- secattr->cache = NULL;
+ memset(secattr, 0, sizeof(*secattr));
}
/**
@@ -248,11 +307,11 @@ static inline void netlbl_secattr_init(struct netlbl_lsm_secattr *secattr)
*/
static inline void netlbl_secattr_destroy(struct netlbl_lsm_secattr *secattr)
{
- if (secattr->cache)
- netlbl_secattr_cache_free(secattr->cache);
kfree(secattr->domain);
- if (secattr->mls_cat)
- netlbl_secattr_catmap_free(secattr->mls_cat);
+ if (secattr->flags & NETLBL_SECATTR_CACHE)
+ netlbl_secattr_cache_free(secattr->cache);
+ if (secattr->flags & NETLBL_SECATTR_MLS_CAT)
+ netlbl_secattr_catmap_free(secattr->attr.mls.cat);
}
/**
@@ -300,7 +359,7 @@ int netlbl_secattr_catmap_setrng(struct netlbl_lsm_secattr_catmap *catmap,
gfp_t flags);
/*
- * LSM protocol operations
+ * LSM protocol operations (NetLabel LSM/kernel API)
*/
int netlbl_enabled(void);
int netlbl_sock_setattr(struct sock *sk,
@@ -308,6 +367,7 @@ int netlbl_sock_setattr(struct sock *sk,
int netlbl_sock_getattr(struct sock *sk,
struct netlbl_lsm_secattr *secattr);
int netlbl_skbuff_getattr(const struct sk_buff *skb,
+ u16 family,
struct netlbl_lsm_secattr *secattr);
void netlbl_skbuff_err(struct sk_buff *skb, int error);
@@ -360,6 +420,7 @@ static inline int netlbl_sock_getattr(struct sock *sk,
return -ENOSYS;
}
static inline int netlbl_skbuff_getattr(const struct sk_buff *skb,
+ u16 family,
struct netlbl_lsm_secattr *secattr)
{
return -ENOSYS;
diff --git a/include/net/netlink.h b/include/net/netlink.h
index 9298218c07f..a5506c42f03 100644
--- a/include/net/netlink.h
+++ b/include/net/netlink.h
@@ -91,6 +91,7 @@
* nla_reserve_nohdr(skb, len) reserve room for an attribute w/o hdr
* nla_put(skb, type, len, data) add attribute to skb
* nla_put_nohdr(skb, len, data) add attribute w/o hdr
+ * nla_append(skb, len, data) append data to skb
*
* Attribute Construction for Basic Types:
* nla_put_u8(skb, type, value) add u8 attribute to skb
@@ -217,6 +218,7 @@ struct nla_policy {
*/
struct nl_info {
struct nlmsghdr *nlh;
+ struct net *nl_net;
u32 pid;
};
@@ -253,6 +255,8 @@ extern int nla_put(struct sk_buff *skb, int attrtype,
int attrlen, const void *data);
extern int nla_put_nohdr(struct sk_buff *skb, int attrlen,
const void *data);
+extern int nla_append(struct sk_buff *skb, int attrlen,
+ const void *data);
/**************************************************************************
* Netlink Messages
@@ -862,7 +866,7 @@ static inline int nla_put_msecs(struct sk_buff *skb, int attrtype,
#define NLA_PUT(skb, attrtype, attrlen, data) \
do { \
- if (nla_put(skb, attrtype, attrlen, data) < 0) \
+ if (unlikely(nla_put(skb, attrtype, attrlen, data) < 0)) \
goto nla_put_failure; \
} while(0)
@@ -881,6 +885,9 @@ static inline int nla_put_msecs(struct sk_buff *skb, int attrtype,
#define NLA_PUT_LE16(skb, attrtype, value) \
NLA_PUT_TYPE(skb, __le16, attrtype, value)
+#define NLA_PUT_BE16(skb, attrtype, value) \
+ NLA_PUT_TYPE(skb, __be16, attrtype, value)
+
#define NLA_PUT_U32(skb, attrtype, value) \
NLA_PUT_TYPE(skb, u32, attrtype, value)
@@ -927,6 +934,15 @@ static inline u16 nla_get_u16(struct nlattr *nla)
}
/**
+ * nla_get_be16 - return payload of __be16 attribute
+ * @nla: __be16 netlink attribute
+ */
+static inline __be16 nla_get_be16(struct nlattr *nla)
+{
+ return *(__be16 *) nla_data(nla);
+}
+
+/**
* nla_get_le16 - return payload of __le16 attribute
* @nla: __le16 netlink attribute
*/
diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h
new file mode 100644
index 00000000000..15a0b052df2
--- /dev/null
+++ b/include/net/netns/ipv4.h
@@ -0,0 +1,31 @@
+/*
+ * ipv4 in net namespaces
+ */
+
+#ifndef __NETNS_IPV4_H__
+#define __NETNS_IPV4_H__
+
+#include <net/inet_frag.h>
+
+struct ctl_table_header;
+struct ipv4_devconf;
+struct fib_rules_ops;
+struct hlist_head;
+struct sock;
+
+struct netns_ipv4 {
+#ifdef CONFIG_SYSCTL
+ struct ctl_table_header *forw_hdr;
+ struct ctl_table_header *frags_hdr;
+#endif
+ struct ipv4_devconf *devconf_all;
+ struct ipv4_devconf *devconf_dflt;
+#ifdef CONFIG_IP_MULTIPLE_TABLES
+ struct fib_rules_ops *rules_ops;
+#endif
+ struct hlist_head *fib_table_hash;
+ struct sock *fibnl;
+
+ struct netns_frags frags;
+};
+#endif
diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h
new file mode 100644
index 00000000000..187c4248df2
--- /dev/null
+++ b/include/net/netns/ipv6.h
@@ -0,0 +1,35 @@
+/*
+ * ipv6 in net namespaces
+ */
+
+#include <net/inet_frag.h>
+
+#ifndef __NETNS_IPV6_H__
+#define __NETNS_IPV6_H__
+
+struct ctl_table_header;
+
+struct netns_sysctl_ipv6 {
+#ifdef CONFIG_SYSCTL
+ struct ctl_table_header *table;
+ struct ctl_table_header *frags_hdr;
+#endif
+ int bindv6only;
+ int flush_delay;
+ int ip6_rt_max_size;
+ int ip6_rt_gc_min_interval;
+ int ip6_rt_gc_timeout;
+ int ip6_rt_gc_interval;
+ int ip6_rt_gc_elasticity;
+ int ip6_rt_mtu_expires;
+ int ip6_rt_min_advmss;
+ int icmpv6_time;
+};
+
+struct netns_ipv6 {
+ struct netns_sysctl_ipv6 sysctl;
+ struct ipv6_devconf *devconf_all;
+ struct ipv6_devconf *devconf_dflt;
+ struct netns_frags frags;
+};
+#endif
diff --git a/include/net/netns/packet.h b/include/net/netns/packet.h
new file mode 100644
index 00000000000..637daf69888
--- /dev/null
+++ b/include/net/netns/packet.h
@@ -0,0 +1,15 @@
+/*
+ * Packet network namespace
+ */
+#ifndef __NETNS_PACKET_H__
+#define __NETNS_PACKET_H__
+
+#include <linux/list.h>
+#include <linux/spinlock.h>
+
+struct netns_packet {
+ rwlock_t sklist_lock;
+ struct hlist_head sklist;
+};
+
+#endif /* __NETNS_PACKET_H__ */
diff --git a/include/net/netns/unix.h b/include/net/netns/unix.h
new file mode 100644
index 00000000000..284649d4dfb
--- /dev/null
+++ b/include/net/netns/unix.h
@@ -0,0 +1,13 @@
+/*
+ * Unix network namespace
+ */
+#ifndef __NETNS_UNIX_H__
+#define __NETNS_UNIX_H__
+
+struct ctl_table_header;
+struct netns_unix {
+ int sysctl_max_dgram_qlen;
+ struct ctl_table_header *ctl;
+};
+
+#endif /* __NETNS_UNIX_H__ */
diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
index f285de69c61..8716eb757d5 100644
--- a/include/net/pkt_cls.h
+++ b/include/net/pkt_cls.h
@@ -2,7 +2,6 @@
#define __NET_PKT_CLS_H
#include <linux/pkt_cls.h>
-#include <net/net_namespace.h>
#include <net/sch_generic.h>
#include <net/act_api.h>
@@ -130,8 +129,8 @@ tcf_exts_exec(struct sk_buff *skb, struct tcf_exts *exts,
return 0;
}
-extern int tcf_exts_validate(struct tcf_proto *tp, struct rtattr **tb,
- struct rtattr *rate_tlv, struct tcf_exts *exts,
+extern int tcf_exts_validate(struct tcf_proto *tp, struct nlattr **tb,
+ struct nlattr *rate_tlv, struct tcf_exts *exts,
struct tcf_ext_map *map);
extern void tcf_exts_destroy(struct tcf_proto *tp, struct tcf_exts *exts);
extern void tcf_exts_change(struct tcf_proto *tp, struct tcf_exts *dst,
@@ -248,7 +247,7 @@ struct tcf_ematch_ops
extern int tcf_em_register(struct tcf_ematch_ops *);
extern int tcf_em_unregister(struct tcf_ematch_ops *);
-extern int tcf_em_tree_validate(struct tcf_proto *, struct rtattr *,
+extern int tcf_em_tree_validate(struct tcf_proto *, struct nlattr *,
struct tcf_ematch_tree *);
extern void tcf_em_tree_destroy(struct tcf_proto *, struct tcf_ematch_tree *);
extern int tcf_em_tree_dump(struct sk_buff *, struct tcf_ematch_tree *, int);
@@ -336,10 +335,12 @@ static inline int tcf_valid_offset(const struct sk_buff *skb,
}
#ifdef CONFIG_NET_CLS_IND
+#include <net/net_namespace.h>
+
static inline int
-tcf_change_indev(struct tcf_proto *tp, char *indev, struct rtattr *indev_tlv)
+tcf_change_indev(struct tcf_proto *tp, char *indev, struct nlattr *indev_tlv)
{
- if (rtattr_strlcpy(indev, indev_tlv, IFNAMSIZ) >= IFNAMSIZ)
+ if (nla_strlcpy(indev, indev_tlv, IFNAMSIZ) >= IFNAMSIZ)
return -EINVAL;
return 0;
}
diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h
index ab61809a961..46fb4d80c74 100644
--- a/include/net/pkt_sched.h
+++ b/include/net/pkt_sched.h
@@ -77,7 +77,7 @@ extern int unregister_qdisc(struct Qdisc_ops *qops);
extern struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle);
extern struct Qdisc *qdisc_lookup_class(struct net_device *dev, u32 handle);
extern struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r,
- struct rtattr *tab);
+ struct nlattr *tab);
extern void qdisc_put_rtab(struct qdisc_rate_table *tab);
extern void __qdisc_run(struct net_device *dev);
diff --git a/include/net/protocol.h b/include/net/protocol.h
index 1166ffb4b3e..ad8c584233a 100644
--- a/include/net/protocol.h
+++ b/include/net/protocol.h
@@ -102,7 +102,7 @@ extern void inet_unregister_protosw(struct inet_protosw *p);
#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
extern int inet6_add_protocol(struct inet6_protocol *prot, unsigned char num);
extern int inet6_del_protocol(struct inet6_protocol *prot, unsigned char num);
-extern void inet6_register_protosw(struct inet_protosw *p);
+extern int inet6_register_protosw(struct inet_protosw *p);
extern void inet6_unregister_protosw(struct inet_protosw *p);
#endif
diff --git a/include/net/raw.h b/include/net/raw.h
index e4af5978194..cca81d8b2d8 100644
--- a/include/net/raw.h
+++ b/include/net/raw.h
@@ -22,27 +22,39 @@
extern struct proto raw_prot;
-extern void raw_err(struct sock *, struct sk_buff *, u32 info);
-extern int raw_rcv(struct sock *, struct sk_buff *);
-
-/* Note: v4 ICMP wants to get at this stuff, if you change the
- * hashing mechanism, make sure you update icmp.c as well.
- */
-#define RAWV4_HTABLE_SIZE MAX_INET_PROTOS
-extern struct hlist_head raw_v4_htable[RAWV4_HTABLE_SIZE];
-
-extern rwlock_t raw_v4_lock;
+void raw_icmp_error(struct sk_buff *, int, u32);
+int raw_local_deliver(struct sk_buff *, int);
+extern int raw_rcv(struct sock *, struct sk_buff *);
-extern struct sock *__raw_v4_lookup(struct sock *sk, unsigned short num,
- __be32 raddr, __be32 laddr,
- int dif);
+#define RAW_HTABLE_SIZE MAX_INET_PROTOS
-extern int raw_v4_input(struct sk_buff *skb, struct iphdr *iph, int hash);
+struct raw_hashinfo {
+ rwlock_t lock;
+ struct hlist_head ht[RAW_HTABLE_SIZE];
+};
#ifdef CONFIG_PROC_FS
extern int raw_proc_init(void);
extern void raw_proc_exit(void);
+
+struct raw_iter_state {
+ struct seq_net_private p;
+ int bucket;
+ unsigned short family;
+ struct raw_hashinfo *h;
+};
+
+#define raw_seq_private(seq) ((struct raw_iter_state *)(seq)->private)
+void *raw_seq_start(struct seq_file *seq, loff_t *pos);
+void *raw_seq_next(struct seq_file *seq, void *v, loff_t *pos);
+void raw_seq_stop(struct seq_file *seq, void *v);
+int raw_seq_open(struct inode *ino, struct file *file, struct raw_hashinfo *h,
+ unsigned short family);
+
#endif
+void raw_hash_sk(struct sock *sk, struct raw_hashinfo *h);
+void raw_unhash_sk(struct sock *sk, struct raw_hashinfo *h);
+
#endif /* _RAW_H */
diff --git a/include/net/rawv6.h b/include/net/rawv6.h
index a5819891d52..8a22599f26b 100644
--- a/include/net/rawv6.h
+++ b/include/net/rawv6.h
@@ -5,26 +5,13 @@
#include <net/protocol.h>
-#define RAWV6_HTABLE_SIZE MAX_INET_PROTOS
-extern struct hlist_head raw_v6_htable[RAWV6_HTABLE_SIZE];
-extern rwlock_t raw_v6_lock;
-
-extern int ipv6_raw_deliver(struct sk_buff *skb, int nexthdr);
-
-extern struct sock *__raw_v6_lookup(struct sock *sk, unsigned short num,
- struct in6_addr *loc_addr, struct in6_addr *rmt_addr,
- int dif);
+void raw6_icmp_error(struct sk_buff *, int nexthdr,
+ int type, int code, int inner_offset, __be32);
+int raw6_local_deliver(struct sk_buff *, int);
extern int rawv6_rcv(struct sock *sk,
struct sk_buff *skb);
-
-extern void rawv6_err(struct sock *sk,
- struct sk_buff *skb,
- struct inet6_skb_parm *opt,
- int type, int code,
- int offset, __be32 info);
-
#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
int rawv6_mh_filter_register(int (*filter)(struct sock *sock,
struct sk_buff *skb));
diff --git a/include/net/route.h b/include/net/route.h
index 59b0b19205a..4eabf008413 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -33,6 +33,7 @@
#include <linux/ip.h>
#include <linux/cache.h>
#include <linux/security.h>
+#include <net/sock.h>
#ifndef __KERNEL__
#warning This file is not supposed to be used outside of kernel.
@@ -110,16 +111,17 @@ extern int ip_rt_init(void);
extern void ip_rt_redirect(__be32 old_gw, __be32 dst, __be32 new_gw,
__be32 src, struct net_device *dev);
extern void rt_cache_flush(int how);
-extern int __ip_route_output_key(struct rtable **, const struct flowi *flp);
-extern int ip_route_output_key(struct rtable **, struct flowi *flp);
-extern int ip_route_output_flow(struct rtable **rp, struct flowi *flp, struct sock *sk, int flags);
+extern int __ip_route_output_key(struct net *, struct rtable **, const struct flowi *flp);
+extern int ip_route_output_key(struct net *, struct rtable **, struct flowi *flp);
+extern int ip_route_output_flow(struct net *, struct rtable **rp, struct flowi *flp, struct sock *sk, int flags);
extern int ip_route_input(struct sk_buff*, __be32 dst, __be32 src, u8 tos, struct net_device *devin);
-extern unsigned short ip_rt_frag_needed(struct iphdr *iph, unsigned short new_mtu);
+extern unsigned short ip_rt_frag_needed(struct net *net, struct iphdr *iph, unsigned short new_mtu);
extern void ip_rt_send_redirect(struct sk_buff *skb);
-extern unsigned inet_addr_type(__be32 addr);
+extern unsigned inet_addr_type(struct net *net, __be32 addr);
+extern unsigned inet_dev_addr_type(struct net *net, const struct net_device *dev, __be32 addr);
extern void ip_rt_multicast_event(struct in_device *);
-extern int ip_rt_ioctl(unsigned int cmd, void __user *arg);
+extern int ip_rt_ioctl(struct net *, unsigned int cmd, void __user *arg);
extern void ip_rt_get_source(u8 *src, struct rtable *rt);
extern int ip_rt_dump(struct sk_buff *skb, struct netlink_callback *cb);
@@ -156,8 +158,9 @@ static inline int ip_route_connect(struct rtable **rp, __be32 dst,
.dport = dport } } };
int err;
+ struct net *net = sk->sk_net;
if (!dst || !src) {
- err = __ip_route_output_key(rp, &fl);
+ err = __ip_route_output_key(net, rp, &fl);
if (err)
return err;
fl.fl4_dst = (*rp)->rt_dst;
@@ -166,7 +169,7 @@ static inline int ip_route_connect(struct rtable **rp, __be32 dst,
*rp = NULL;
}
security_sk_classify_flow(sk, &fl);
- return ip_route_output_flow(rp, &fl, sk, flags);
+ return ip_route_output_flow(net, rp, &fl, sk, flags);
}
static inline int ip_route_newports(struct rtable **rp, u8 protocol,
@@ -183,7 +186,7 @@ static inline int ip_route_newports(struct rtable **rp, u8 protocol,
ip_rt_put(*rp);
*rp = NULL;
security_sk_classify_flow(sk, &fl);
- return ip_route_output_flow(rp, &fl, sk, 0);
+ return ip_route_output_flow(sk->sk_net, rp, &fl, sk, 0);
}
return 0;
}
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index 4c3b35153c3..ab502ec1c61 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -66,7 +66,7 @@ struct Qdisc_class_ops
unsigned long (*get)(struct Qdisc *, u32 classid);
void (*put)(struct Qdisc *, unsigned long);
int (*change)(struct Qdisc *, u32, u32,
- struct rtattr **, unsigned long *);
+ struct nlattr **, unsigned long *);
int (*delete)(struct Qdisc *, unsigned long);
void (*walk)(struct Qdisc *, struct qdisc_walker * arg);
@@ -86,7 +86,7 @@ struct Qdisc_class_ops
struct Qdisc_ops
{
struct Qdisc_ops *next;
- struct Qdisc_class_ops *cl_ops;
+ const struct Qdisc_class_ops *cl_ops;
char id[IFNAMSIZ];
int priv_size;
@@ -95,10 +95,10 @@ struct Qdisc_ops
int (*requeue)(struct sk_buff *, struct Qdisc *);
unsigned int (*drop)(struct Qdisc *);
- int (*init)(struct Qdisc *, struct rtattr *arg);
+ int (*init)(struct Qdisc *, struct nlattr *arg);
void (*reset)(struct Qdisc *);
void (*destroy)(struct Qdisc *);
- int (*change)(struct Qdisc *, struct rtattr *arg);
+ int (*change)(struct Qdisc *, struct nlattr *arg);
int (*dump)(struct Qdisc *, struct sk_buff *);
int (*dump_stats)(struct Qdisc *, struct gnet_dump *);
@@ -126,7 +126,7 @@ struct tcf_proto_ops
unsigned long (*get)(struct tcf_proto*, u32 handle);
void (*put)(struct tcf_proto*, unsigned long);
int (*change)(struct tcf_proto*, unsigned long,
- u32 handle, struct rtattr **,
+ u32 handle, struct nlattr **,
unsigned long *);
int (*delete)(struct tcf_proto*, unsigned long);
void (*walk)(struct tcf_proto*, struct tcf_walker *arg);
diff --git a/include/net/sctp/checksum.h b/include/net/sctp/checksum.h
new file mode 100644
index 00000000000..ba75c67cb99
--- /dev/null
+++ b/include/net/sctp/checksum.h
@@ -0,0 +1,78 @@
+/* SCTP kernel reference Implementation
+ * Copyright (c) 1999-2001 Motorola, Inc.
+ * Copyright (c) 2001-2003 International Business Machines, Corp.
+ *
+ * This file is part of the SCTP kernel reference Implementation
+ *
+ * SCTP Checksum functions
+ *
+ * The SCTP reference implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP reference implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ * lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ * http://www.sf.net/projects/lksctp
+ *
+ * Written or modified by:
+ * Dinakaran Joseph
+ * Jon Grimm <jgrimm@us.ibm.com>
+ * Sridhar Samudrala <sri@us.ibm.com>
+ *
+ * Rewritten to use libcrc32c by:
+ * Vlad Yasevich <vladislav.yasevich@hp.com>
+ *
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ */
+
+#include <linux/types.h>
+#include <net/sctp/sctp.h>
+#include <linux/crc32c.h>
+
+static inline __u32 sctp_start_cksum(__u8 *buffer, __u16 length)
+{
+ __u32 crc = ~(__u32) 0;
+ __u8 zero[sizeof(__u32)] = {0};
+
+ /* Optimize this routine to be SCTP specific, knowing how
+ * to skip the checksum field of the SCTP header.
+ */
+
+ /* Calculate CRC up to the checksum. */
+ crc = crc32c(crc, buffer, sizeof(struct sctphdr) - sizeof(__u32));
+
+ /* Skip checksum field of the header. */
+ crc = crc32c(crc, zero, sizeof(__u32));
+
+ /* Calculate the rest of the CRC. */
+ crc = crc32c(crc, &buffer[sizeof(struct sctphdr)],
+ length - sizeof(struct sctphdr));
+ return crc;
+}
+
+static inline __u32 sctp_update_cksum(__u8 *buffer, __u16 length, __u32 crc32)
+{
+ return crc32c(crc32, buffer, length);
+}
+
+static inline __u32 sctp_end_cksum(__u32 crc32)
+{
+ return ntohl(~crc32);
+}
diff --git a/include/net/sctp/constants.h b/include/net/sctp/constants.h
index 05f22a6afbc..fefcba67bd1 100644
--- a/include/net/sctp/constants.h
+++ b/include/net/sctp/constants.h
@@ -365,36 +365,12 @@ typedef enum {
* Also, RFC 8.4, non-unicast addresses are not considered valid SCTP
* addresses.
*/
-#define IS_IPV4_UNUSABLE_ADDRESS(a) \
- ((htonl(INADDR_BROADCAST) == *a) || \
- (MULTICAST(*a)) || \
- (((unsigned char *)(a))[0] == 0) || \
- ((((unsigned char *)(a))[0] == 198) && \
- (((unsigned char *)(a))[1] == 18) && \
- (((unsigned char *)(a))[2] == 0)) || \
- ((((unsigned char *)(a))[0] == 192) && \
- (((unsigned char *)(a))[1] == 88) && \
- (((unsigned char *)(a))[2] == 99)))
-
-/* IPv4 Link-local addresses: 169.254.0.0/16. */
-#define IS_IPV4_LINK_ADDRESS(a) \
- ((((unsigned char *)(a))[0] == 169) && \
- (((unsigned char *)(a))[1] == 254))
-
-/* RFC 1918 "Address Allocation for Private Internets" defines the IPv4
- * private address space as the following:
- *
- * 10.0.0.0 - 10.255.255.255 (10/8 prefix)
- * 172.16.0.0.0 - 172.31.255.255 (172.16/12 prefix)
- * 192.168.0.0 - 192.168.255.255 (192.168/16 prefix)
- */
-#define IS_IPV4_PRIVATE_ADDRESS(a) \
- ((((unsigned char *)(a))[0] == 10) || \
- ((((unsigned char *)(a))[0] == 172) && \
- (((unsigned char *)(a))[1] >= 16) && \
- (((unsigned char *)(a))[1] < 32)) || \
- ((((unsigned char *)(a))[0] == 192) && \
- (((unsigned char *)(a))[1] == 168)))
+#define IS_IPV4_UNUSABLE_ADDRESS(a) \
+ ((htonl(INADDR_BROADCAST) == a) || \
+ ipv4_is_multicast(a) || \
+ ipv4_is_zeronet(a) || \
+ ipv4_is_test_198(a) || \
+ ipv4_is_anycast_6to4(a))
/* Flags used for the bind address copy functions. */
#define SCTP_ADDR6_ALLOWED 0x00000001 /* IPv6 address is allowed by
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index 34318a33a94..4977b0a8153 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -150,13 +150,6 @@ int sctp_primitive_REQUESTHEARTBEAT(struct sctp_association *, void *arg);
int sctp_primitive_ASCONF(struct sctp_association *, void *arg);
/*
- * sctp/crc32c.c
- */
-__u32 sctp_start_cksum(__u8 *ptr, __u16 count);
-__u32 sctp_update_cksum(__u8 *ptr, __u16 count, __u32 cksum);
-__u32 sctp_end_cksum(__u32 cksum);
-
-/*
* sctp/input.c
*/
int sctp_rcv(struct sk_buff *skb);
@@ -470,8 +463,7 @@ static inline void sctp_skb_set_owner_r(struct sk_buff *skb, struct sock *sk)
skb->destructor = sctp_sock_rfree;
atomic_add(event->rmem_len, &sk->sk_rmem_alloc);
/*
- * This mimics the behavior of
- * sk_stream_set_owner_r
+ * This mimics the behavior of skb_set_owner_r
*/
sk->sk_forward_alloc -= event->rmem_len;
}
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index bb965742b64..4d591bfce45 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -451,6 +451,7 @@ union sctp_params {
struct sctp_random_param *random;
struct sctp_chunks_param *chunks;
struct sctp_hmac_algo_param *hmac_algo;
+ struct sctp_addip_param *addip;
};
/* RFC 2960. Section 3.3.5 Heartbeat.
@@ -743,6 +744,7 @@ struct sctp_chunk {
__u8 tsn_missing_report; /* Data chunk missing counter. */
__u8 data_accepted; /* At least 1 chunk in this packet accepted */
__u8 auth; /* IN: was auth'ed | OUT: needs auth */
+ __u8 has_asconf; /* IN: have seen an asconf before */
};
void sctp_chunk_hold(struct sctp_chunk *);
@@ -758,12 +760,18 @@ void sctp_init_addrs(struct sctp_chunk *, union sctp_addr *,
union sctp_addr *);
const union sctp_addr *sctp_source(const struct sctp_chunk *chunk);
+enum {
+ SCTP_ADDR_NEW, /* new address added to assoc/ep */
+ SCTP_ADDR_SRC, /* address can be used as source */
+ SCTP_ADDR_DEL, /* address about to be deleted */
+};
+
/* This is a structure for holding either an IPv6 or an IPv4 address. */
struct sctp_sockaddr_entry {
struct list_head list;
struct rcu_head rcu;
union sctp_addr a;
- __u8 use_as_src;
+ __u8 state;
__u8 valid;
};
@@ -1188,10 +1196,12 @@ int sctp_bind_addr_dup(struct sctp_bind_addr *dest,
const struct sctp_bind_addr *src,
gfp_t gfp);
int sctp_add_bind_addr(struct sctp_bind_addr *, union sctp_addr *,
- __u8 use_as_src, gfp_t gfp);
+ __u8 addr_state, gfp_t gfp);
int sctp_del_bind_addr(struct sctp_bind_addr *, union sctp_addr *);
int sctp_bind_addr_match(struct sctp_bind_addr *, const union sctp_addr *,
struct sctp_sock *);
+int sctp_bind_addr_state(const struct sctp_bind_addr *bp,
+ const union sctp_addr *addr);
union sctp_addr *sctp_find_unmatch_addr(struct sctp_bind_addr *bp,
const union sctp_addr *addrs,
int addrcnt,
@@ -1784,20 +1794,16 @@ struct sctp_association {
*/
struct sctp_chunk *addip_last_asconf;
- /* ADDIP Section 4.2 Upon reception of an ASCONF Chunk.
+ /* ADDIP Section 5.2 Upon reception of an ASCONF Chunk.
*
- * IMPLEMENTATION NOTE: As an optimization a receiver may wish
- * to save the last ASCONF-ACK for some predetermined period
- * of time and instead of re-processing the ASCONF (with the
- * same serial number) it may just re-transmit the
- * ASCONF-ACK. It may wish to use the arrival of a new serial
- * number to discard the previously saved ASCONF-ACK or any
- * other means it may choose to expire the saved ASCONF-ACK.
+ * This is needed to implement itmes E1 - E4 of the updated
+ * spec. Here is the justification:
*
- * [This is our saved ASCONF-ACK. We invalidate it when a new
- * ASCONF serial number arrives.]
+ * Since the peer may bundle multiple ASCONF chunks toward us,
+ * we now need the ability to cache multiple ACKs. The section
+ * describes in detail how they are cached and cleaned up.
*/
- struct sctp_chunk *addip_last_asconf_ack;
+ struct list_head asconf_ack_list;
/* These ASCONF chunks are waiting to be sent.
*
@@ -1938,12 +1944,19 @@ void sctp_assoc_rwnd_increase(struct sctp_association *, unsigned);
void sctp_assoc_rwnd_decrease(struct sctp_association *, unsigned);
void sctp_assoc_set_primary(struct sctp_association *,
struct sctp_transport *);
+void sctp_assoc_del_nonprimary_peers(struct sctp_association *,
+ struct sctp_transport *);
int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *,
gfp_t);
int sctp_assoc_set_bind_addr_from_cookie(struct sctp_association *,
struct sctp_cookie*,
gfp_t gfp);
int sctp_assoc_set_id(struct sctp_association *, gfp_t);
+void sctp_assoc_clean_asconf_ack_cache(const struct sctp_association *asoc);
+struct sctp_chunk *sctp_assoc_lookup_asconf_ack(
+ const struct sctp_association *asoc,
+ __be32 serial);
+
int sctp_cmp_addr_exact(const union sctp_addr *ss1,
const union sctp_addr *ss2);
diff --git a/include/net/snmp.h b/include/net/snmp.h
index ea206bff0dc..ce2f4850751 100644
--- a/include/net/snmp.h
+++ b/include/net/snmp.h
@@ -23,6 +23,7 @@
#include <linux/cache.h>
#include <linux/snmp.h>
+#include <linux/smp.h>
/*
* Mibs are stored in array of unsigned long.
@@ -117,6 +118,11 @@ struct linux_mib {
unsigned long mibs[LINUX_MIB_MAX];
};
+/* Linux Xfrm */
+#define LINUX_MIB_XFRMMAX __LINUX_MIB_XFRMMAX
+struct linux_xfrm_mib {
+ unsigned long mibs[LINUX_MIB_XFRMMAX];
+};
/*
* FIXME: On x86 and some other CPUs the split into user and softirq parts
@@ -134,17 +140,27 @@ struct linux_mib {
#define SNMP_INC_STATS_BH(mib, field) \
(per_cpu_ptr(mib[0], raw_smp_processor_id())->mibs[field]++)
-#define SNMP_INC_STATS_OFFSET_BH(mib, field, offset) \
- (per_cpu_ptr(mib[0], raw_smp_processor_id())->mibs[field + (offset)]++)
#define SNMP_INC_STATS_USER(mib, field) \
- (per_cpu_ptr(mib[1], raw_smp_processor_id())->mibs[field]++)
+ do { \
+ per_cpu_ptr(mib[1], get_cpu())->mibs[field]++; \
+ put_cpu(); \
+ } while (0)
#define SNMP_INC_STATS(mib, field) \
- (per_cpu_ptr(mib[!in_softirq()], raw_smp_processor_id())->mibs[field]++)
+ do { \
+ per_cpu_ptr(mib[!in_softirq()], get_cpu())->mibs[field]++; \
+ put_cpu(); \
+ } while (0)
#define SNMP_DEC_STATS(mib, field) \
- (per_cpu_ptr(mib[!in_softirq()], raw_smp_processor_id())->mibs[field]--)
+ do { \
+ per_cpu_ptr(mib[!in_softirq()], get_cpu())->mibs[field]--; \
+ put_cpu(); \
+ } while (0)
#define SNMP_ADD_STATS_BH(mib, field, addend) \
(per_cpu_ptr(mib[0], raw_smp_processor_id())->mibs[field] += addend)
#define SNMP_ADD_STATS_USER(mib, field, addend) \
- (per_cpu_ptr(mib[1], raw_smp_processor_id())->mibs[field] += addend)
+ do { \
+ per_cpu_ptr(mib[1], get_cpu())->mibs[field] += addend; \
+ put_cpu(); \
+ } while (0)
#endif
diff --git a/include/net/sock.h b/include/net/sock.h
index 6e1542da33a..902324488d0 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -47,6 +47,7 @@
#include <linux/module.h>
#include <linux/lockdep.h>
#include <linux/netdevice.h>
+#include <linux/pcounter.h>
#include <linux/skbuff.h> /* struct sk_buff */
#include <linux/mm.h>
#include <linux/security.h>
@@ -56,7 +57,6 @@
#include <asm/atomic.h>
#include <net/dst.h>
#include <net/checksum.h>
-#include <net/net_namespace.h>
/*
* This structure really needs to be cleaned up.
@@ -94,6 +94,7 @@ typedef struct {
struct sock;
struct proto;
+struct net;
/**
* struct sock_common - minimal network layer representation of sockets
@@ -145,7 +146,8 @@ struct sock_common {
* @sk_forward_alloc: space allocated forward
* @sk_allocation: allocation mode
* @sk_sndbuf: size of send buffer in bytes
- * @sk_flags: %SO_LINGER (l_onoff), %SO_BROADCAST, %SO_KEEPALIVE, %SO_OOBINLINE settings
+ * @sk_flags: %SO_LINGER (l_onoff), %SO_BROADCAST, %SO_KEEPALIVE,
+ * %SO_OOBINLINE settings
* @sk_no_check: %SO_NO_CHECK setting, wether or not checkup packets
* @sk_route_caps: route capabilities (e.g. %NETIF_F_TSO)
* @sk_gso_type: GSO type (e.g. %SKB_GSO_TCPV4)
@@ -153,9 +155,12 @@ struct sock_common {
* @sk_backlog: always used with the per-socket spinlock held
* @sk_callback_lock: used with the callbacks in the end of this struct
* @sk_error_queue: rarely used
- * @sk_prot_creator: sk_prot of original sock creator (see ipv6_setsockopt, IPV6_ADDRFORM for instance)
+ * @sk_prot_creator: sk_prot of original sock creator (see ipv6_setsockopt,
+ * IPV6_ADDRFORM for instance)
* @sk_err: last error
- * @sk_err_soft: errors that don't cause failure but are the cause of a persistent failure not just 'timed out'
+ * @sk_err_soft: errors that don't cause failure but are the cause of a
+ * persistent failure not just 'timed out'
+ * @sk_drops: raw drops counter
* @sk_ack_backlog: current listen backlog
* @sk_max_ack_backlog: listen backlog set in listen()
* @sk_priority: %SO_PRIORITY setting
@@ -239,6 +244,7 @@ struct sock {
rwlock_t sk_callback_lock;
int sk_err,
sk_err_soft;
+ atomic_t sk_drops;
unsigned short sk_ack_backlog;
unsigned short sk_max_ack_backlog;
__u32 sk_priority;
@@ -439,7 +445,7 @@ static inline int sk_acceptq_is_full(struct sock *sk)
*/
static inline int sk_stream_min_wspace(struct sock *sk)
{
- return sk->sk_wmem_queued / 2;
+ return sk->sk_wmem_queued >> 1;
}
static inline int sk_stream_wspace(struct sock *sk)
@@ -454,25 +460,6 @@ static inline int sk_stream_memory_free(struct sock *sk)
return sk->sk_wmem_queued < sk->sk_sndbuf;
}
-extern void sk_stream_rfree(struct sk_buff *skb);
-
-static inline void sk_stream_set_owner_r(struct sk_buff *skb, struct sock *sk)
-{
- skb->sk = sk;
- skb->destructor = sk_stream_rfree;
- atomic_add(skb->truesize, &sk->sk_rmem_alloc);
- sk->sk_forward_alloc -= skb->truesize;
-}
-
-static inline void sk_stream_free_skb(struct sock *sk, struct sk_buff *skb)
-{
- skb_truesize_check(skb);
- sock_set_flag(sk, SOCK_QUEUE_SHRUNK);
- sk->sk_wmem_queued -= skb->truesize;
- sk->sk_forward_alloc += skb->truesize;
- __kfree_skb(skb);
-}
-
/* The per-socket spinlock must be held here. */
static inline void sk_add_backlog(struct sock *sk, struct sk_buff *skb)
{
@@ -560,14 +547,11 @@ struct proto {
void (*unhash)(struct sock *sk);
int (*get_port)(struct sock *sk, unsigned short snum);
-#ifdef CONFIG_SMP
/* Keeping track of sockets in use */
- void (*inuse_add)(struct proto *prot, int inc);
- int (*inuse_getval)(const struct proto *prot);
- int *inuse_ptr;
-#else
- int inuse;
+#ifdef CONFIG_PROC_FS
+ struct pcounter inuse;
#endif
+
/* Memory pressure */
void (*enter_memory_pressure)(void);
atomic_t *memory_allocated; /* Current allocated memory. */
@@ -575,7 +559,7 @@ struct proto {
/*
* Pressure flag: try to collapse.
* Technical note: it is used by multiple contexts non atomically.
- * All the sk_stream_mem_schedule() is of this nature: accounting
+ * All the __sk_mem_schedule() is of this nature: accounting
* is strict, actions are advisory and have some latency.
*/
int *memory_pressure;
@@ -602,36 +586,6 @@ struct proto {
#endif
};
-/*
- * Special macros to let protos use a fast version of inuse{get|add}
- * using a static percpu variable per proto instead of an allocated one,
- * saving one dereference.
- * This might be changed if/when dynamic percpu vars become fast.
- */
-#ifdef CONFIG_SMP
-# define DEFINE_PROTO_INUSE(NAME) \
-static DEFINE_PER_CPU(int, NAME##_inuse); \
-static void NAME##_inuse_add(struct proto *prot, int inc) \
-{ \
- __get_cpu_var(NAME##_inuse) += inc; \
-} \
- \
-static int NAME##_inuse_getval(const struct proto *prot)\
-{ \
- int res = 0, cpu; \
- \
- for_each_possible_cpu(cpu) \
- res += per_cpu(NAME##_inuse, cpu); \
- return res; \
-}
-# define REF_PROTO_INUSE(NAME) \
- .inuse_add = NAME##_inuse_add, \
- .inuse_getval = NAME##_inuse_getval,
-#else
-# define DEFINE_PROTO_INUSE(NAME)
-# define REF_PROTO_INUSE(NAME)
-#endif
-
extern int proto_register(struct proto *prot, int alloc_slab);
extern void proto_unregister(struct proto *prot);
@@ -660,33 +614,42 @@ static inline void sk_refcnt_debug_release(const struct sock *sk)
#define sk_refcnt_debug_release(sk) do { } while (0)
#endif /* SOCK_REFCNT_DEBUG */
+
+#ifdef CONFIG_PROC_FS
+# define DEFINE_PROTO_INUSE(NAME) DEFINE_PCOUNTER(NAME)
+# define REF_PROTO_INUSE(NAME) PCOUNTER_MEMBER_INITIALIZER(NAME, .inuse)
/* Called with local bh disabled */
-static __inline__ void sock_prot_inc_use(struct proto *prot)
+static inline void sock_prot_inuse_add(struct proto *prot, int inc)
{
-#ifdef CONFIG_SMP
- prot->inuse_add(prot, 1);
-#else
- prot->inuse++;
-#endif
+ pcounter_add(&prot->inuse, inc);
}
-
-static __inline__ void sock_prot_dec_use(struct proto *prot)
+static inline int sock_prot_inuse_init(struct proto *proto)
{
-#ifdef CONFIG_SMP
- prot->inuse_add(prot, -1);
-#else
- prot->inuse--;
-#endif
+ return pcounter_alloc(&proto->inuse);
}
-
-static __inline__ int sock_prot_inuse(struct proto *proto)
+static inline int sock_prot_inuse_get(struct proto *proto)
{
-#ifdef CONFIG_SMP
- return proto->inuse_getval(proto);
+ return pcounter_getval(&proto->inuse);
+}
+static inline void sock_prot_inuse_free(struct proto *proto)
+{
+ pcounter_free(&proto->inuse);
+}
#else
- return proto->inuse;
-#endif
+# define DEFINE_PROTO_INUSE(NAME)
+# define REF_PROTO_INUSE(NAME)
+static void inline sock_prot_inuse_add(struct proto *prot, int inc)
+{
+}
+static int inline sock_prot_inuse_init(struct proto *proto)
+{
+ return 0;
}
+static void inline sock_prot_inuse_free(struct proto *proto)
+{
+}
+#endif
+
/* With per-bucket locks this operation is not-atomic, so that
* this version is not worse.
@@ -750,32 +713,81 @@ static inline struct inode *SOCK_INODE(struct socket *socket)
return &container_of(socket, struct socket_alloc, socket)->vfs_inode;
}
-extern void __sk_stream_mem_reclaim(struct sock *sk);
-extern int sk_stream_mem_schedule(struct sock *sk, int size, int kind);
+/*
+ * Functions for memory accounting
+ */
+extern int __sk_mem_schedule(struct sock *sk, int size, int kind);
+extern void __sk_mem_reclaim(struct sock *sk);
-#define SK_STREAM_MEM_QUANTUM ((int)PAGE_SIZE)
+#define SK_MEM_QUANTUM ((int)PAGE_SIZE)
+#define SK_MEM_QUANTUM_SHIFT ilog2(SK_MEM_QUANTUM)
+#define SK_MEM_SEND 0
+#define SK_MEM_RECV 1
-static inline int sk_stream_pages(int amt)
+static inline int sk_mem_pages(int amt)
{
- return DIV_ROUND_UP(amt, SK_STREAM_MEM_QUANTUM);
+ return (amt + SK_MEM_QUANTUM - 1) >> SK_MEM_QUANTUM_SHIFT;
}
-static inline void sk_stream_mem_reclaim(struct sock *sk)
+static inline int sk_has_account(struct sock *sk)
{
- if (sk->sk_forward_alloc >= SK_STREAM_MEM_QUANTUM)
- __sk_stream_mem_reclaim(sk);
+ /* return true if protocol supports memory accounting */
+ return !!sk->sk_prot->memory_allocated;
}
-static inline int sk_stream_rmem_schedule(struct sock *sk, struct sk_buff *skb)
+static inline int sk_wmem_schedule(struct sock *sk, int size)
{
- return (int)skb->truesize <= sk->sk_forward_alloc ||
- sk_stream_mem_schedule(sk, skb->truesize, 1);
+ if (!sk_has_account(sk))
+ return 1;
+ return size <= sk->sk_forward_alloc ||
+ __sk_mem_schedule(sk, size, SK_MEM_SEND);
}
-static inline int sk_stream_wmem_schedule(struct sock *sk, int size)
+static inline int sk_rmem_schedule(struct sock *sk, int size)
{
+ if (!sk_has_account(sk))
+ return 1;
return size <= sk->sk_forward_alloc ||
- sk_stream_mem_schedule(sk, size, 0);
+ __sk_mem_schedule(sk, size, SK_MEM_RECV);
+}
+
+static inline void sk_mem_reclaim(struct sock *sk)
+{
+ if (!sk_has_account(sk))
+ return;
+ if (sk->sk_forward_alloc >= SK_MEM_QUANTUM)
+ __sk_mem_reclaim(sk);
+}
+
+static inline void sk_mem_reclaim_partial(struct sock *sk)
+{
+ if (!sk_has_account(sk))
+ return;
+ if (sk->sk_forward_alloc > SK_MEM_QUANTUM)
+ __sk_mem_reclaim(sk);
+}
+
+static inline void sk_mem_charge(struct sock *sk, int size)
+{
+ if (!sk_has_account(sk))
+ return;
+ sk->sk_forward_alloc -= size;
+}
+
+static inline void sk_mem_uncharge(struct sock *sk, int size)
+{
+ if (!sk_has_account(sk))
+ return;
+ sk->sk_forward_alloc += size;
+}
+
+static inline void sk_wmem_free_skb(struct sock *sk, struct sk_buff *skb)
+{
+ skb_truesize_check(skb);
+ sock_set_flag(sk, SOCK_QUEUE_SHRUNK);
+ sk->sk_wmem_queued -= skb->truesize;
+ sk_mem_uncharge(sk, skb->truesize);
+ __kfree_skb(skb);
}
/* Used by processes to "lock" a socket state, so that
@@ -812,14 +824,14 @@ do { \
lockdep_init_map(&(sk)->sk_lock.dep_map, (name), (key), 0); \
} while (0)
-extern void FASTCALL(lock_sock_nested(struct sock *sk, int subclass));
+extern void lock_sock_nested(struct sock *sk, int subclass);
static inline void lock_sock(struct sock *sk)
{
lock_sock_nested(sk, 0);
}
-extern void FASTCALL(release_sock(struct sock *sk));
+extern void release_sock(struct sock *sk);
/* BH context may only use the following locking interface. */
#define bh_lock_sock(__sk) spin_lock(&((__sk)->sk_lock.slock))
@@ -1113,12 +1125,6 @@ static inline int sk_can_gso(const struct sock *sk)
extern void sk_setup_caps(struct sock *sk, struct dst_entry *dst);
-static inline void sk_charge_skb(struct sock *sk, struct sk_buff *skb)
-{
- sk->sk_wmem_queued += skb->truesize;
- sk->sk_forward_alloc -= skb->truesize;
-}
-
static inline int skb_copy_to_page(struct sock *sk, char __user *from,
struct sk_buff *skb, struct page *page,
int off, int copy)
@@ -1138,7 +1144,7 @@ static inline int skb_copy_to_page(struct sock *sk, char __user *from,
skb->data_len += copy;
skb->truesize += copy;
sk->sk_wmem_queued += copy;
- sk->sk_forward_alloc -= copy;
+ sk_mem_charge(sk, copy);
return 0;
}
@@ -1164,6 +1170,7 @@ static inline void skb_set_owner_r(struct sk_buff *skb, struct sock *sk)
skb->sk = sk;
skb->destructor = sock_rfree;
atomic_add(skb->truesize, &sk->sk_rmem_alloc);
+ sk_mem_charge(sk, skb->truesize);
}
extern void sk_reset_timer(struct sock *sk, struct timer_list* timer,
@@ -1225,45 +1232,12 @@ static inline void sk_wake_async(struct sock *sk, int how, int band)
static inline void sk_stream_moderate_sndbuf(struct sock *sk)
{
if (!(sk->sk_userlocks & SOCK_SNDBUF_LOCK)) {
- sk->sk_sndbuf = min(sk->sk_sndbuf, sk->sk_wmem_queued / 2);
+ sk->sk_sndbuf = min(sk->sk_sndbuf, sk->sk_wmem_queued >> 1);
sk->sk_sndbuf = max(sk->sk_sndbuf, SOCK_MIN_SNDBUF);
}
}
-static inline struct sk_buff *sk_stream_alloc_pskb(struct sock *sk,
- int size, int mem,
- gfp_t gfp)
-{
- struct sk_buff *skb;
-
- /* The TCP header must be at least 32-bit aligned. */
- size = ALIGN(size, 4);
-
- skb = alloc_skb_fclone(size + sk->sk_prot->max_header, gfp);
- if (skb) {
- skb->truesize += mem;
- if (sk_stream_wmem_schedule(sk, skb->truesize)) {
- /*
- * Make sure that we have exactly size bytes
- * available to the caller, no more, no less.
- */
- skb_reserve(skb, skb_tailroom(skb) - size);
- return skb;
- }
- __kfree_skb(skb);
- } else {
- sk->sk_prot->enter_memory_pressure();
- sk_stream_moderate_sndbuf(sk);
- }
- return NULL;
-}
-
-static inline struct sk_buff *sk_stream_alloc_skb(struct sock *sk,
- int size,
- gfp_t gfp)
-{
- return sk_stream_alloc_pskb(sk, size, 0, gfp);
-}
+struct sk_buff *sk_stream_alloc_skb(struct sock *sk, int size, gfp_t gfp);
static inline struct page *sk_stream_alloc_page(struct sock *sk)
{
@@ -1282,7 +1256,7 @@ static inline struct page *sk_stream_alloc_page(struct sock *sk)
*/
static inline int sock_writeable(const struct sock *sk)
{
- return atomic_read(&sk->sk_wmem_alloc) < (sk->sk_sndbuf / 2);
+ return atomic_read(&sk->sk_wmem_alloc) < (sk->sk_sndbuf >> 1);
}
static inline gfp_t gfp_any(void)
@@ -1391,23 +1365,11 @@ extern int net_msg_warn;
lock_sock(sk); \
}
-static inline void sock_valbool_flag(struct sock *sk, int bit, int valbool)
-{
- if (valbool)
- sock_set_flag(sk, bit);
- else
- sock_reset_flag(sk, bit);
-}
-
extern __u32 sysctl_wmem_max;
extern __u32 sysctl_rmem_max;
extern void sk_init(void);
-#ifdef CONFIG_SYSCTL
-extern struct ctl_table core_table[];
-#endif
-
extern int sysctl_optmem_max;
extern __u32 sysctl_wmem_default;
diff --git a/include/net/tcp.h b/include/net/tcp.h
index cb5b033e0e5..7de4ea3a04d 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -309,6 +309,9 @@ extern int tcp_twsk_unique(struct sock *sk,
extern void tcp_twsk_destructor(struct sock *sk);
+extern ssize_t tcp_splice_read(struct socket *sk, loff_t *ppos,
+ struct pipe_inode_info *pipe, size_t len, unsigned int flags);
+
static inline void tcp_dec_quickack_mode(struct sock *sk,
const unsigned int pkts)
{
@@ -575,10 +578,6 @@ struct tcp_skb_cb {
#define TCPCB_EVER_RETRANS 0x80 /* Ever retransmitted frame */
#define TCPCB_RETRANS (TCPCB_SACKED_RETRANS|TCPCB_EVER_RETRANS)
-#define TCPCB_URG 0x20 /* Urgent pointer advanced here */
-
-#define TCPCB_AT_TAIL (TCPCB_URG)
-
__u16 urg_ptr; /* Valid w/URG flags is set. */
__u32 ack_seq; /* Sequence number ACK'd */
};
@@ -649,7 +648,7 @@ struct tcp_congestion_ops {
/* lower bound for congestion window (optional) */
u32 (*min_cwnd)(const struct sock *sk);
/* do new cwnd calculation (required) */
- void (*cong_avoid)(struct sock *sk, u32 ack, u32 in_flight, int good_ack);
+ void (*cong_avoid)(struct sock *sk, u32 ack, u32 in_flight);
/* call before changing ca_state (optional) */
void (*set_state)(struct sock *sk, u8 new_state);
/* call when cwnd event occurs (optional) */
@@ -680,7 +679,7 @@ extern void tcp_slow_start(struct tcp_sock *tp);
extern struct tcp_congestion_ops tcp_init_congestion_ops;
extern u32 tcp_reno_ssthresh(struct sock *sk);
-extern void tcp_reno_cong_avoid(struct sock *sk, u32 ack, u32 in_flight, int flag);
+extern void tcp_reno_cong_avoid(struct sock *sk, u32 ack, u32 in_flight);
extern u32 tcp_reno_min_cwnd(const struct sock *sk);
extern struct tcp_congestion_ops tcp_reno;
@@ -782,26 +781,12 @@ static __inline__ __u32 tcp_max_burst(const struct tcp_sock *tp)
return 3;
}
-/* RFC2861 Check whether we are limited by application or congestion window
- * This is the inverse of cwnd check in tcp_tso_should_defer
- */
-static inline int tcp_is_cwnd_limited(const struct sock *sk, u32 in_flight)
+/* Returns end sequence number of the receiver's advertised window */
+static inline u32 tcp_wnd_end(const struct tcp_sock *tp)
{
- const struct tcp_sock *tp = tcp_sk(sk);
- u32 left;
-
- if (in_flight >= tp->snd_cwnd)
- return 1;
-
- if (!sk_can_gso(sk))
- return 0;
-
- left = tp->snd_cwnd - in_flight;
- if (sysctl_tcp_tso_win_divisor)
- return left * sysctl_tcp_tso_win_divisor < tp->snd_cwnd;
- else
- return left <= tcp_max_burst(tp);
+ return tp->snd_una + tp->snd_wnd;
}
+extern int tcp_is_cwnd_limited(const struct sock *sk, u32 in_flight);
static inline void tcp_minshall_update(struct tcp_sock *tp, unsigned int mss,
const struct sk_buff *skb)
@@ -921,40 +906,7 @@ static const char *statename[]={
"Close Wait","Last ACK","Listen","Closing"
};
#endif
-
-static inline void tcp_set_state(struct sock *sk, int state)
-{
- int oldstate = sk->sk_state;
-
- switch (state) {
- case TCP_ESTABLISHED:
- if (oldstate != TCP_ESTABLISHED)
- TCP_INC_STATS(TCP_MIB_CURRESTAB);
- break;
-
- case TCP_CLOSE:
- if (oldstate == TCP_CLOSE_WAIT || oldstate == TCP_ESTABLISHED)
- TCP_INC_STATS(TCP_MIB_ESTABRESETS);
-
- sk->sk_prot->unhash(sk);
- if (inet_csk(sk)->icsk_bind_hash &&
- !(sk->sk_userlocks & SOCK_BINDPORT_LOCK))
- inet_put_port(&tcp_hashinfo, sk);
- /* fall through */
- default:
- if (oldstate==TCP_ESTABLISHED)
- TCP_DEC_STATS(TCP_MIB_CURRESTAB);
- }
-
- /* Change state AFTER socket is unhashed to avoid closed
- * socket sitting in hash tables.
- */
- sk->sk_state = state;
-
-#ifdef STATE_TRACE
- SOCK_DEBUG(sk, "TCP sk=%p, State %s -> %s\n",sk, statename[oldstate],statename[state]);
-#endif
-}
+extern void tcp_set_state(struct sock *sk, int state);
extern void tcp_done(struct sock *sk);
@@ -1078,7 +1030,6 @@ static inline void tcp_clear_retrans_hints_partial(struct tcp_sock *tp)
static inline void tcp_clear_all_retrans_hints(struct tcp_sock *tp)
{
tcp_clear_retrans_hints_partial(tp);
- tp->fastpath_skb_hint = NULL;
}
/* MD5 Signature */
@@ -1153,7 +1104,8 @@ extern int tcp_v4_calc_md5_hash(char *md5_hash,
struct dst_entry *dst,
struct request_sock *req,
struct tcphdr *th,
- int protocol, int tcplen);
+ int protocol,
+ unsigned int tcplen);
extern struct tcp_md5sig_key *tcp_v4_md5_lookup(struct sock *sk,
struct sock *addr_sk);
@@ -1193,8 +1145,8 @@ static inline void tcp_write_queue_purge(struct sock *sk)
struct sk_buff *skb;
while ((skb = __skb_dequeue(&sk->sk_write_queue)) != NULL)
- sk_stream_free_skb(sk, skb);
- sk_stream_mem_reclaim(sk);
+ sk_wmem_free_skb(sk, skb);
+ sk_mem_reclaim(sk);
}
static inline struct sk_buff *tcp_write_queue_head(struct sock *sk)
@@ -1227,6 +1179,11 @@ static inline struct sk_buff *tcp_write_queue_next(struct sock *sk, struct sk_bu
for (; (skb != (struct sk_buff *)&(sk)->sk_write_queue);\
skb = skb->next)
+#define tcp_for_write_queue_from_safe(skb, tmp, sk) \
+ for (tmp = skb->next; \
+ (skb != (struct sk_buff *)&(sk)->sk_write_queue); \
+ skb = tmp, tmp = skb->next)
+
static inline struct sk_buff *tcp_send_head(struct sock *sk)
{
return sk->sk_send_head;
@@ -1234,14 +1191,9 @@ static inline struct sk_buff *tcp_send_head(struct sock *sk)
static inline void tcp_advance_send_head(struct sock *sk, struct sk_buff *skb)
{
- struct tcp_sock *tp = tcp_sk(sk);
-
sk->sk_send_head = skb->next;
if (sk->sk_send_head == (struct sk_buff *)&sk->sk_write_queue)
sk->sk_send_head = NULL;
- /* Don't override Nagle indefinately with F-RTO */
- if (tp->frto_counter == 2)
- tp->frto_counter = 3;
}
static inline void tcp_check_send_head(struct sock *sk, struct sk_buff *skb_unlinked)
@@ -1265,8 +1217,12 @@ static inline void tcp_add_write_queue_tail(struct sock *sk, struct sk_buff *skb
__tcp_add_write_queue_tail(sk, skb);
/* Queue it, remembering where we must start sending. */
- if (sk->sk_send_head == NULL)
+ if (sk->sk_send_head == NULL) {
sk->sk_send_head = skb;
+
+ if (tcp_sk(sk)->highest_sack == NULL)
+ tcp_sk(sk)->highest_sack = skb;
+ }
}
static inline void __tcp_add_write_queue_head(struct sock *sk, struct sk_buff *skb)
@@ -1309,6 +1265,45 @@ static inline int tcp_write_queue_empty(struct sock *sk)
return skb_queue_empty(&sk->sk_write_queue);
}
+/* Start sequence of the highest skb with SACKed bit, valid only if
+ * sacked > 0 or when the caller has ensured validity by itself.
+ */
+static inline u32 tcp_highest_sack_seq(struct tcp_sock *tp)
+{
+ if (!tp->sacked_out)
+ return tp->snd_una;
+
+ if (tp->highest_sack == NULL)
+ return tp->snd_nxt;
+
+ return TCP_SKB_CB(tp->highest_sack)->seq;
+}
+
+static inline void tcp_advance_highest_sack(struct sock *sk, struct sk_buff *skb)
+{
+ tcp_sk(sk)->highest_sack = tcp_skb_is_last(sk, skb) ? NULL :
+ tcp_write_queue_next(sk, skb);
+}
+
+static inline struct sk_buff *tcp_highest_sack(struct sock *sk)
+{
+ return tcp_sk(sk)->highest_sack;
+}
+
+static inline void tcp_highest_sack_reset(struct sock *sk)
+{
+ tcp_sk(sk)->highest_sack = tcp_write_queue_head(sk);
+}
+
+/* Called when old skb is about to be deleted (to be combined with new skb) */
+static inline void tcp_highest_sack_combine(struct sock *sk,
+ struct sk_buff *old,
+ struct sk_buff *new)
+{
+ if (tcp_sk(sk)->sacked_out && (old == tcp_sk(sk)->highest_sack))
+ tcp_sk(sk)->highest_sack = new;
+}
+
/* /proc */
enum tcp_seq_states {
TCP_SEQ_STATE_LISTENING,
@@ -1359,7 +1354,8 @@ struct tcp_sock_af_ops {
struct dst_entry *dst,
struct request_sock *req,
struct tcphdr *th,
- int protocol, int len);
+ int protocol,
+ unsigned int len);
int (*md5_add) (struct sock *sk,
struct sock *addr_sk,
u8 *newkey,
diff --git a/include/net/transp_v6.h b/include/net/transp_v6.h
index 409da3a9a45..27394e0447d 100644
--- a/include/net/transp_v6.h
+++ b/include/net/transp_v6.h
@@ -17,16 +17,20 @@ extern struct proto tcpv6_prot;
struct flowi;
/* extention headers */
-extern void ipv6_rthdr_init(void);
-extern void ipv6_frag_init(void);
-extern void ipv6_nodata_init(void);
-extern void ipv6_destopt_init(void);
+extern int ipv6_exthdrs_init(void);
+extern void ipv6_exthdrs_exit(void);
+extern int ipv6_frag_init(void);
+extern void ipv6_frag_exit(void);
/* transport protocols */
-extern void rawv6_init(void);
-extern void udpv6_init(void);
-extern void udplitev6_init(void);
-extern void tcpv6_init(void);
+extern int rawv6_init(void);
+extern void rawv6_exit(void);
+extern int udpv6_init(void);
+extern void udpv6_exit(void);
+extern int udplitev6_init(void);
+extern void udplitev6_exit(void);
+extern int tcpv6_init(void);
+extern void tcpv6_exit(void);
extern int udpv6_connect(struct sock *sk,
struct sockaddr *uaddr,
diff --git a/include/net/udp.h b/include/net/udp.h
index 98755ebaf16..c6669c0a74c 100644
--- a/include/net/udp.h
+++ b/include/net/udp.h
@@ -65,6 +65,13 @@ extern rwlock_t udp_hash_lock;
extern struct proto udp_prot;
+extern atomic_t udp_memory_allocated;
+
+/* sysctl variables for udp */
+extern int sysctl_udp_mem[3];
+extern int sysctl_udp_rmem_min;
+extern int sysctl_udp_wmem_min;
+
struct sk_buff;
/*
@@ -108,7 +115,7 @@ static inline void udp_lib_unhash(struct sock *sk)
write_lock_bh(&udp_hash_lock);
if (sk_del_node_init(sk)) {
inet_sk(sk)->num = 0;
- sock_prot_dec_use(sk->sk_prot);
+ sock_prot_inuse_add(sk->sk_prot, -1);
}
write_unlock_bh(&udp_hash_lock);
}
@@ -139,6 +146,12 @@ extern int udp_lib_setsockopt(struct sock *sk, int level, int optname,
int (*push_pending_frames)(struct sock *));
DECLARE_SNMP_STAT(struct udp_mib, udp_statistics);
+DECLARE_SNMP_STAT(struct udp_mib, udp_stats_in6);
+
+/* UDP-Lite does not have a standardized MIB yet, so we inherit from UDP */
+DECLARE_SNMP_STAT(struct udp_mib, udplite_statistics);
+DECLARE_SNMP_STAT(struct udp_mib, udplite_stats_in6);
+
/*
* SNMP statistics for UDP and UDP-Lite
*/
@@ -149,6 +162,25 @@ DECLARE_SNMP_STAT(struct udp_mib, udp_statistics);
if (is_udplite) SNMP_INC_STATS_BH(udplite_statistics, field); \
else SNMP_INC_STATS_BH(udp_statistics, field); } while(0)
+#define UDP6_INC_STATS_BH(field, is_udplite) do { \
+ if (is_udplite) SNMP_INC_STATS_BH(udplite_stats_in6, field); \
+ else SNMP_INC_STATS_BH(udp_stats_in6, field); } while(0)
+#define UDP6_INC_STATS_USER(field, is_udplite) do { \
+ if (is_udplite) SNMP_INC_STATS_USER(udplite_stats_in6, field); \
+ else SNMP_INC_STATS_USER(udp_stats_in6, field); } while(0)
+
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+#define UDPX_INC_STATS_BH(sk, field) \
+ do { \
+ if ((sk)->sk_family == AF_INET) \
+ UDP_INC_STATS_BH(field, 0); \
+ else \
+ UDP6_INC_STATS_BH(field, 0); \
+ } while (0);
+#else
+#define UDPX_INC_STATS_BH(sk, field) UDP_INC_STATS_BH(field, 0)
+#endif
+
/* /proc */
struct udp_seq_afinfo {
struct module *owner;
@@ -173,4 +205,6 @@ extern void udp_proc_unregister(struct udp_seq_afinfo *afinfo);
extern int udp4_proc_init(void);
extern void udp4_proc_exit(void);
#endif
+
+extern void udp_init(void);
#endif /* _UDP_H */
diff --git a/include/net/udplite.h b/include/net/udplite.h
index 635b0eafca9..b76b2e377af 100644
--- a/include/net/udplite.h
+++ b/include/net/udplite.h
@@ -13,9 +13,6 @@
extern struct proto udplite_prot;
extern struct hlist_head udplite_hash[UDP_HTABLE_SIZE];
-/* UDP-Lite does not have a standardized MIB yet, so we inherit from UDP */
-DECLARE_SNMP_STAT(struct udp_mib, udplite_statistics);
-
/*
* Checksum computation is all in software, hence simpler getfrag.
*/
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 1dd20cf1798..5ebb9ba479b 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -19,6 +19,9 @@
#include <net/route.h>
#include <net/ipv6.h>
#include <net/ip6_fib.h>
+#ifdef CONFIG_XFRM_STATISTICS
+#include <net/snmp.h>
+#endif
#define XFRM_PROTO_ESP 50
#define XFRM_PROTO_AH 51
@@ -34,6 +37,17 @@
#define MODULE_ALIAS_XFRM_TYPE(family, proto) \
MODULE_ALIAS("xfrm-type-" __stringify(family) "-" __stringify(proto))
+#ifdef CONFIG_XFRM_STATISTICS
+DECLARE_SNMP_STAT(struct linux_xfrm_mib, xfrm_statistics);
+#define XFRM_INC_STATS(field) SNMP_INC_STATS(xfrm_statistics, field)
+#define XFRM_INC_STATS_BH(field) SNMP_INC_STATS_BH(xfrm_statistics, field)
+#define XFRM_INC_STATS_USER(field) SNMP_INC_STATS_USER(xfrm_statistics, field)
+#else
+#define XFRM_INC_STATS(field)
+#define XFRM_INC_STATS_BH(field)
+#define XFRM_INC_STATS_USER(field)
+#endif
+
extern struct sock *xfrm_nl;
extern u32 sysctl_xfrm_aevent_etime;
extern u32 sysctl_xfrm_aevent_rseqth;
@@ -183,7 +197,7 @@ struct xfrm_state
struct timer_list timer;
/* Last used time */
- u64 lastused;
+ unsigned long lastused;
/* Reference to data common to all the instances of this
* transformer. */
@@ -227,22 +241,26 @@ struct km_event
u32 event;
};
+struct net_device;
struct xfrm_type;
struct xfrm_dst;
struct xfrm_policy_afinfo {
unsigned short family;
struct dst_ops *dst_ops;
void (*garbage_collect)(void);
- int (*dst_lookup)(struct xfrm_dst **dst, struct flowi *fl);
+ struct dst_entry *(*dst_lookup)(int tos, xfrm_address_t *saddr,
+ xfrm_address_t *daddr);
int (*get_saddr)(xfrm_address_t *saddr, xfrm_address_t *daddr);
struct dst_entry *(*find_bundle)(struct flowi *fl, struct xfrm_policy *policy);
- int (*bundle_create)(struct xfrm_policy *policy,
- struct xfrm_state **xfrm,
- int nx,
- struct flowi *fl,
- struct dst_entry **dst_p);
void (*decode_session)(struct sk_buff *skb,
- struct flowi *fl);
+ struct flowi *fl,
+ int reverse);
+ int (*get_tos)(struct flowi *fl);
+ int (*init_path)(struct xfrm_dst *path,
+ struct dst_entry *dst,
+ int nfheader_len);
+ int (*fill_dst)(struct xfrm_dst *xdst,
+ struct net_device *dev);
};
extern int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo);
@@ -257,6 +275,8 @@ extern int __xfrm_state_delete(struct xfrm_state *x);
struct xfrm_state_afinfo {
unsigned int family;
+ unsigned int proto;
+ unsigned int eth_proto;
struct module *owner;
struct xfrm_type *type_map[IPPROTO_MAX];
struct xfrm_mode *mode_map[XFRM_MODE_MAX];
@@ -267,6 +287,12 @@ struct xfrm_state_afinfo {
int (*tmpl_sort)(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n);
int (*state_sort)(struct xfrm_state **dst, struct xfrm_state **src, int n);
int (*output)(struct sk_buff *skb);
+ int (*extract_input)(struct xfrm_state *x,
+ struct sk_buff *skb);
+ int (*extract_output)(struct xfrm_state *x,
+ struct sk_buff *skb);
+ int (*transport_finish)(struct sk_buff *skb,
+ int async);
};
extern int xfrm_state_register_afinfo(struct xfrm_state_afinfo *afinfo);
@@ -282,6 +308,8 @@ struct xfrm_type
__u8 flags;
#define XFRM_TYPE_NON_FRAGMENT 1
#define XFRM_TYPE_REPLAY_PROT 2
+#define XFRM_TYPE_LOCAL_COADDR 4
+#define XFRM_TYPE_REMOTE_COADDR 8
int (*init_state)(struct xfrm_state *x);
void (*destructor)(struct xfrm_state *);
@@ -289,8 +317,6 @@ struct xfrm_type
int (*output)(struct xfrm_state *, struct sk_buff *pskb);
int (*reject)(struct xfrm_state *, struct sk_buff *, struct flowi *);
int (*hdr_offset)(struct xfrm_state *, struct sk_buff *, u8 **);
- xfrm_address_t *(*local_addr)(struct xfrm_state *, xfrm_address_t *);
- xfrm_address_t *(*remote_addr)(struct xfrm_state *, xfrm_address_t *);
/* Estimate maximal size of result of transformation of a dgram */
u32 (*get_mtu)(struct xfrm_state *, int size);
};
@@ -299,6 +325,27 @@ extern int xfrm_register_type(struct xfrm_type *type, unsigned short family);
extern int xfrm_unregister_type(struct xfrm_type *type, unsigned short family);
struct xfrm_mode {
+ /*
+ * Remove encapsulation header.
+ *
+ * The IP header will be moved over the top of the encapsulation
+ * header.
+ *
+ * On entry, the transport header shall point to where the IP header
+ * should be and the network header shall be set to where the IP
+ * header currently is. skb->data shall point to the start of the
+ * payload.
+ */
+ int (*input2)(struct xfrm_state *x, struct sk_buff *skb);
+
+ /*
+ * This is the actual input entry point.
+ *
+ * For transport mode and equivalent this would be identical to
+ * input2 (which does not need to be set). While tunnel mode
+ * and equivalent would set this to the tunnel encapsulation function
+ * xfrm4_prepare_input that would in turn call input2.
+ */
int (*input)(struct xfrm_state *x, struct sk_buff *skb);
/*
@@ -312,7 +359,18 @@ struct xfrm_mode {
* header. The value of the network header will always point
* to the top IP header while skb->data will point to the payload.
*/
- int (*output)(struct xfrm_state *x,struct sk_buff *skb);
+ int (*output2)(struct xfrm_state *x,struct sk_buff *skb);
+
+ /*
+ * This is the actual output entry point.
+ *
+ * For transport mode and equivalent this would be identical to
+ * output2 (which does not need to be set). While tunnel mode
+ * and equivalent would set this to a tunnel encapsulation function
+ * (xfrm4_prepare_output or xfrm6_prepare_output) that would in turn
+ * call output2.
+ */
+ int (*output)(struct xfrm_state *x, struct sk_buff *skb);
struct xfrm_state_afinfo *afinfo;
struct module *owner;
@@ -454,6 +512,51 @@ struct xfrm_skb_cb {
#define XFRM_SKB_CB(__skb) ((struct xfrm_skb_cb *)&((__skb)->cb[0]))
+/*
+ * This structure is used by the afinfo prepare_input/prepare_output functions
+ * to transmit header information to the mode input/output functions.
+ */
+struct xfrm_mode_skb_cb {
+ union {
+ struct inet_skb_parm h4;
+ struct inet6_skb_parm h6;
+ } header;
+
+ /* Copied from header for IPv4, always set to zero and DF for IPv6. */
+ __be16 id;
+ __be16 frag_off;
+
+ /* TOS for IPv4, class for IPv6. */
+ u8 tos;
+
+ /* TTL for IPv4, hop limitfor IPv6. */
+ u8 ttl;
+
+ /* Protocol for IPv4, NH for IPv6. */
+ u8 protocol;
+
+ /* Used by IPv6 only, zero for IPv4. */
+ u8 flow_lbl[3];
+};
+
+#define XFRM_MODE_SKB_CB(__skb) ((struct xfrm_mode_skb_cb *)&((__skb)->cb[0]))
+
+/*
+ * This structure is used by the input processing to locate the SPI and
+ * related information.
+ */
+struct xfrm_spi_skb_cb {
+ union {
+ struct inet_skb_parm h4;
+ struct inet6_skb_parm h6;
+ } header;
+
+ unsigned int daddroff;
+ unsigned int family;
+};
+
+#define XFRM_SPI_SKB_CB(__skb) ((struct xfrm_spi_skb_cb *)&((__skb)->cb[0]))
+
/* Audit Information */
struct xfrm_audit
{
@@ -462,41 +565,59 @@ struct xfrm_audit
};
#ifdef CONFIG_AUDITSYSCALL
-static inline struct audit_buffer *xfrm_audit_start(u32 auid, u32 sid)
+static inline struct audit_buffer *xfrm_audit_start(const char *op)
{
struct audit_buffer *audit_buf = NULL;
- char *secctx;
- u32 secctx_len;
+ if (audit_enabled == 0)
+ return NULL;
audit_buf = audit_log_start(current->audit_context, GFP_ATOMIC,
- AUDIT_MAC_IPSEC_EVENT);
+ AUDIT_MAC_IPSEC_EVENT);
if (audit_buf == NULL)
return NULL;
+ audit_log_format(audit_buf, "op=%s", op);
+ return audit_buf;
+}
- audit_log_format(audit_buf, "auid=%u", auid);
+static inline void xfrm_audit_helper_usrinfo(u32 auid, u32 secid,
+ struct audit_buffer *audit_buf)
+{
+ char *secctx;
+ u32 secctx_len;
- if (sid != 0 &&
- security_secid_to_secctx(sid, &secctx, &secctx_len) == 0) {
+ audit_log_format(audit_buf, " auid=%u", auid);
+ if (secid != 0 &&
+ security_secid_to_secctx(secid, &secctx, &secctx_len) == 0) {
audit_log_format(audit_buf, " subj=%s", secctx);
security_release_secctx(secctx, secctx_len);
} else
audit_log_task_context(audit_buf);
- return audit_buf;
}
extern void xfrm_audit_policy_add(struct xfrm_policy *xp, int result,
- u32 auid, u32 sid);
+ u32 auid, u32 secid);
extern void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result,
- u32 auid, u32 sid);
+ u32 auid, u32 secid);
extern void xfrm_audit_state_add(struct xfrm_state *x, int result,
- u32 auid, u32 sid);
+ u32 auid, u32 secid);
extern void xfrm_audit_state_delete(struct xfrm_state *x, int result,
- u32 auid, u32 sid);
+ u32 auid, u32 secid);
+extern void xfrm_audit_state_replay_overflow(struct xfrm_state *x,
+ struct sk_buff *skb);
+extern void xfrm_audit_state_notfound_simple(struct sk_buff *skb, u16 family);
+extern void xfrm_audit_state_notfound(struct sk_buff *skb, u16 family,
+ __be32 net_spi, __be32 net_seq);
+extern void xfrm_audit_state_icvfail(struct xfrm_state *x,
+ struct sk_buff *skb, u8 proto);
#else
#define xfrm_audit_policy_add(x, r, a, s) do { ; } while (0)
#define xfrm_audit_policy_delete(x, r, a, s) do { ; } while (0)
#define xfrm_audit_state_add(x, r, a, s) do { ; } while (0)
#define xfrm_audit_state_delete(x, r, a, s) do { ; } while (0)
+#define xfrm_audit_state_replay_overflow(x, s) do { ; } while (0)
+#define xfrm_audit_state_notfound_simple(s, f) do { ; } while (0)
+#define xfrm_audit_state_notfound(s, f, sp, sq) do { ; } while (0)
+#define xfrm_audit_state_icvfail(x, s, p) do { ; } while (0)
#endif /* CONFIG_AUDITSYSCALL */
static inline void xfrm_pol_hold(struct xfrm_policy *policy)
@@ -505,12 +626,12 @@ static inline void xfrm_pol_hold(struct xfrm_policy *policy)
atomic_inc(&policy->refcnt);
}
-extern void __xfrm_policy_destroy(struct xfrm_policy *policy);
+extern void xfrm_policy_destroy(struct xfrm_policy *policy);
static inline void xfrm_pol_put(struct xfrm_policy *policy)
{
if (atomic_dec_and_test(&policy->refcnt))
- __xfrm_policy_destroy(policy);
+ xfrm_policy_destroy(policy);
}
#ifdef CONFIG_XFRM_SUB_POLICY
@@ -757,17 +878,25 @@ xfrm_state_addr_cmp(struct xfrm_tmpl *tmpl, struct xfrm_state *x, unsigned short
}
#ifdef CONFIG_XFRM
-
extern int __xfrm_policy_check(struct sock *, int dir, struct sk_buff *skb, unsigned short family);
-static inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, unsigned short family)
+static inline int __xfrm_policy_check2(struct sock *sk, int dir,
+ struct sk_buff *skb,
+ unsigned int family, int reverse)
{
+ int ndir = dir | (reverse ? XFRM_POLICY_MASK + 1 : 0);
+
if (sk && sk->sk_policy[XFRM_POLICY_IN])
- return __xfrm_policy_check(sk, dir, skb, family);
+ return __xfrm_policy_check(sk, ndir, skb, family);
return (!xfrm_policy_count[dir] && !skb->sp) ||
(skb->dst->flags & DST_NOPOLICY) ||
- __xfrm_policy_check(sk, dir, skb, family);
+ __xfrm_policy_check(sk, ndir, skb, family);
+}
+
+static inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, unsigned short family)
+{
+ return __xfrm_policy_check2(sk, dir, skb, family, 0);
}
static inline int xfrm4_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
@@ -780,7 +909,34 @@ static inline int xfrm6_policy_check(struct sock *sk, int dir, struct sk_buff *s
return xfrm_policy_check(sk, dir, skb, AF_INET6);
}
-extern int xfrm_decode_session(struct sk_buff *skb, struct flowi *fl, unsigned short family);
+static inline int xfrm4_policy_check_reverse(struct sock *sk, int dir,
+ struct sk_buff *skb)
+{
+ return __xfrm_policy_check2(sk, dir, skb, AF_INET, 1);
+}
+
+static inline int xfrm6_policy_check_reverse(struct sock *sk, int dir,
+ struct sk_buff *skb)
+{
+ return __xfrm_policy_check2(sk, dir, skb, AF_INET6, 1);
+}
+
+extern int __xfrm_decode_session(struct sk_buff *skb, struct flowi *fl,
+ unsigned int family, int reverse);
+
+static inline int xfrm_decode_session(struct sk_buff *skb, struct flowi *fl,
+ unsigned int family)
+{
+ return __xfrm_decode_session(skb, fl, family, 0);
+}
+
+static inline int xfrm_decode_session_reverse(struct sk_buff *skb,
+ struct flowi *fl,
+ unsigned int family)
+{
+ return __xfrm_decode_session(skb, fl, family, 1);
+}
+
extern int __xfrm_route_forward(struct sk_buff *skb, unsigned short family);
static inline int xfrm_route_forward(struct sk_buff *skb, unsigned short family)
@@ -841,6 +997,22 @@ static inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *sk
{
return 1;
}
+static inline int xfrm_decode_session_reverse(struct sk_buff *skb,
+ struct flowi *fl,
+ unsigned int family)
+{
+ return -ENOSYS;
+}
+static inline int xfrm4_policy_check_reverse(struct sock *sk, int dir,
+ struct sk_buff *skb)
+{
+ return 1;
+}
+static inline int xfrm6_policy_check_reverse(struct sock *sk, int dir,
+ struct sk_buff *skb)
+{
+ return 1;
+}
#endif
static __inline__
@@ -981,12 +1153,27 @@ struct xfrm6_tunnel {
extern void xfrm_init(void);
extern void xfrm4_init(void);
-extern void xfrm6_init(void);
-extern void xfrm6_fini(void);
extern void xfrm_state_init(void);
extern void xfrm4_state_init(void);
-extern void xfrm6_state_init(void);
+#ifdef CONFIG_XFRM
+extern int xfrm6_init(void);
+extern void xfrm6_fini(void);
+extern int xfrm6_state_init(void);
extern void xfrm6_state_fini(void);
+#else
+static inline int xfrm6_init(void)
+{
+ return 0;
+}
+static inline void xfrm6_fini(void)
+{
+ ;
+}
+#endif
+
+#ifdef CONFIG_XFRM_STATISTICS
+extern int xfrm_proc_init(void);
+#endif
extern int xfrm_state_walk(u8 proto, int (*func)(struct xfrm_state *, int, void*), void *);
extern struct xfrm_state *xfrm_state_alloc(void);
@@ -1045,14 +1232,23 @@ extern int xfrm_state_delete(struct xfrm_state *x);
extern int xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info);
extern void xfrm_sad_getinfo(struct xfrmk_sadinfo *si);
extern void xfrm_spd_getinfo(struct xfrmk_spdinfo *si);
-extern int xfrm_replay_check(struct xfrm_state *x, __be32 seq);
+extern int xfrm_replay_check(struct xfrm_state *x,
+ struct sk_buff *skb, __be32 seq);
extern void xfrm_replay_advance(struct xfrm_state *x, __be32 seq);
extern void xfrm_replay_notify(struct xfrm_state *x, int event);
extern int xfrm_state_mtu(struct xfrm_state *x, int mtu);
extern int xfrm_init_state(struct xfrm_state *x);
+extern int xfrm_prepare_input(struct xfrm_state *x, struct sk_buff *skb);
+extern int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi,
+ int encap_type);
+extern int xfrm_input_resume(struct sk_buff *skb, int nexthdr);
+extern int xfrm_output_resume(struct sk_buff *skb, int err);
extern int xfrm_output(struct sk_buff *skb);
+extern int xfrm4_extract_header(struct sk_buff *skb);
+extern int xfrm4_extract_input(struct xfrm_state *x, struct sk_buff *skb);
extern int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
int encap_type);
+extern int xfrm4_transport_finish(struct sk_buff *skb, int async);
extern int xfrm4_rcv(struct sk_buff *skb);
static inline int xfrm4_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi)
@@ -1060,10 +1256,15 @@ static inline int xfrm4_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi)
return xfrm4_rcv_encap(skb, nexthdr, spi, 0);
}
+extern int xfrm4_extract_output(struct xfrm_state *x, struct sk_buff *skb);
+extern int xfrm4_prepare_output(struct xfrm_state *x, struct sk_buff *skb);
extern int xfrm4_output(struct sk_buff *skb);
extern int xfrm4_tunnel_register(struct xfrm_tunnel *handler, unsigned short family);
extern int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler, unsigned short family);
+extern int xfrm6_extract_header(struct sk_buff *skb);
+extern int xfrm6_extract_input(struct xfrm_state *x, struct sk_buff *skb);
extern int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi);
+extern int xfrm6_transport_finish(struct sk_buff *skb, int async);
extern int xfrm6_rcv(struct sk_buff *skb);
extern int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
xfrm_address_t *saddr, u8 proto);
@@ -1072,6 +1273,8 @@ extern int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler, unsigned short
extern __be32 xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr);
extern void xfrm6_tunnel_free_spi(xfrm_address_t *saddr);
extern __be32 xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr);
+extern int xfrm6_extract_output(struct xfrm_state *x, struct sk_buff *skb);
+extern int xfrm6_prepare_output(struct xfrm_state *x, struct sk_buff *skb);
extern int xfrm6_output(struct sk_buff *skb);
extern int xfrm6_find_1stfragopt(struct xfrm_state *x, struct sk_buff *skb,
u8 **prevhdr);
@@ -1079,7 +1282,6 @@ extern int xfrm6_find_1stfragopt(struct xfrm_state *x, struct sk_buff *skb,
#ifdef CONFIG_XFRM
extern int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb);
extern int xfrm_user_policy(struct sock *sk, int optname, u8 __user *optval, int optlen);
-extern int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl, unsigned short family);
#else
static inline int xfrm_user_policy(struct sock *sk, int optname, u8 __user *optval, int optlen)
{
@@ -1092,11 +1294,6 @@ static inline int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb)
kfree_skb(skb);
return 0;
}
-
-static inline int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl, unsigned short family)
-{
- return -EINVAL;
-}
#endif
struct xfrm_policy *xfrm_policy_alloc(gfp_t gfp);
@@ -1113,11 +1310,9 @@ extern int xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi);
struct xfrm_state * xfrm_find_acq(u8 mode, u32 reqid, u8 proto,
xfrm_address_t *daddr, xfrm_address_t *saddr,
int create, unsigned short family);
-extern int xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info);
extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol);
extern int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *xdst,
struct flowi *fl, int family, int strict);
-extern void xfrm_init_pmtu(struct dst_entry *dst);
#ifdef CONFIG_XFRM_MIGRATE
extern int km_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
@@ -1214,4 +1409,9 @@ static inline void xfrm_states_delete(struct xfrm_state **states, int n)
}
#endif
+static inline struct xfrm_state *xfrm_input_state(struct sk_buff *skb)
+{
+ return skb->sp->xvec[skb->sp->len - 1];
+}
+
#endif /* _NET_XFRM_H */