Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6

* 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6: (24 commits)
  xfrm: Add security check before flushing SAD/SPD
  [NET_SCHED]: Fix filter double free
  [NET]: Avoid duplicate netlink notification when changing link state
  [UDP]: Revert 2-pass hashing changes.
  [AF_UNIX]: Fix stream recvmsg() race.
  [NETFILTER]: nf_conntrack_amanda: fix textsearch_prepare() error check
  [NETFILTER]: ip_tables: fix compat related crash
  [NETFILTER]: nf_conntrack: fix helper module unload races
  [RTNETLINK]: ifindex 0 does not exist
  [NETLINK]: Mark netlink policies const
  [TCP] tcp_probe: Attach printf attribute properly to printl().
  [TCP]: Use LIMIT_NETDEBUG in tcp_retransmit_timer().
  [NET]: Merge dst_discard_in and dst_discard_out.
  [RFKILL]: Make rfkill->name const
  [IPV4]: Restore old behaviour of default config values
  [IPV4]: Add default config support after inetdev_init
  [IPV4]: Convert IPv4 devconf to an array
  [IPV4]: Only panic if inetdev_init fails for loopback
  [TCP]: Honour sk_bound_dev_if in tcp_v4_send_ack
  [BNX2]: Update version and reldate.
  ...
This commit is contained in:
Linus Torvalds 2007-06-07 17:08:06 -07:00
commit df3872a966
63 changed files with 751 additions and 658 deletions

View File

@ -672,7 +672,7 @@ static int c2_up(struct net_device *netdev)
* rdma interface.
*/
in_dev = in_dev_get(netdev);
in_dev->cnf.arp_ignore = 1;
IN_DEV_CONF_SET(in_dev, ARP_IGNORE, 1);
in_dev_put(in_dev);
return 0;

View File

@ -54,8 +54,8 @@
#define DRV_MODULE_NAME "bnx2"
#define PFX DRV_MODULE_NAME ": "
#define DRV_MODULE_VERSION "1.5.10"
#define DRV_MODULE_RELDATE "May 1, 2007"
#define DRV_MODULE_VERSION "1.5.11"
#define DRV_MODULE_RELDATE "June 4, 2007"
#define RUN_AT(x) (jiffies + (x))
@ -1778,6 +1778,15 @@ bnx2_init_5709_context(struct bnx2 *bp)
val = BNX2_CTX_COMMAND_ENABLED | BNX2_CTX_COMMAND_MEM_INIT | (1 << 12);
val |= (BCM_PAGE_BITS - 8) << 16;
REG_WR(bp, BNX2_CTX_COMMAND, val);
for (i = 0; i < 10; i++) {
val = REG_RD(bp, BNX2_CTX_COMMAND);
if (!(val & BNX2_CTX_COMMAND_MEM_INIT))
break;
udelay(2);
}
if (val & BNX2_CTX_COMMAND_MEM_INIT)
return -EBUSY;
for (i = 0; i < bp->ctx_pages; i++) {
int j;
@ -1811,6 +1820,7 @@ bnx2_init_context(struct bnx2 *bp)
vcid = 96;
while (vcid) {
u32 vcid_addr, pcid_addr, offset;
int i;
vcid--;
@ -1831,16 +1841,20 @@ bnx2_init_context(struct bnx2 *bp)
pcid_addr = vcid_addr;
}
REG_WR(bp, BNX2_CTX_VIRT_ADDR, 0x00);
REG_WR(bp, BNX2_CTX_PAGE_TBL, pcid_addr);
for (i = 0; i < (CTX_SIZE / PHY_CTX_SIZE); i++) {
vcid_addr += (i << PHY_CTX_SHIFT);
pcid_addr += (i << PHY_CTX_SHIFT);
/* Zero out the context. */
for (offset = 0; offset < PHY_CTX_SIZE; offset += 4) {
CTX_WR(bp, 0x00, offset, 0);
REG_WR(bp, BNX2_CTX_VIRT_ADDR, 0x00);
REG_WR(bp, BNX2_CTX_PAGE_TBL, pcid_addr);
/* Zero out the context. */
for (offset = 0; offset < PHY_CTX_SIZE; offset += 4)
CTX_WR(bp, 0x00, offset, 0);
REG_WR(bp, BNX2_CTX_VIRT_ADDR, vcid_addr);
REG_WR(bp, BNX2_CTX_PAGE_TBL, pcid_addr);
}
REG_WR(bp, BNX2_CTX_VIRT_ADDR, vcid_addr);
REG_WR(bp, BNX2_CTX_PAGE_TBL, pcid_addr);
}
}
@ -3691,9 +3705,11 @@ bnx2_init_chip(struct bnx2 *bp)
/* Initialize context mapping and zero out the quick contexts. The
* context block must have already been enabled. */
if (CHIP_NUM(bp) == CHIP_NUM_5709)
bnx2_init_5709_context(bp);
else
if (CHIP_NUM(bp) == CHIP_NUM_5709) {
rc = bnx2_init_5709_context(bp);
if (rc)
return rc;
} else
bnx2_init_context(bp);
if ((rc = bnx2_init_cpus(bp)) != 0)
@ -3772,7 +3788,10 @@ bnx2_init_chip(struct bnx2 *bp)
REG_WR(bp, BNX2_HC_CMD_TICKS,
(bp->cmd_ticks_int << 16) | bp->cmd_ticks);
REG_WR(bp, BNX2_HC_STATS_TICKS, bp->stats_ticks & 0xffff00);
if (CHIP_NUM(bp) == CHIP_NUM_5708)
REG_WR(bp, BNX2_HC_STATS_TICKS, 0);
else
REG_WR(bp, BNX2_HC_STATS_TICKS, bp->stats_ticks & 0xffff00);
REG_WR(bp, BNX2_HC_STAT_COLLECT_TICKS, 0xbb8); /* 3ms */
if (CHIP_ID(bp) == CHIP_ID_5706_A1)
@ -3799,6 +3818,11 @@ bnx2_init_chip(struct bnx2 *bp)
/* Initialize the receive filter. */
bnx2_set_rx_mode(bp->dev);
if (CHIP_NUM(bp) == CHIP_NUM_5709) {
val = REG_RD(bp, BNX2_MISC_NEW_CORE_CTL);
val |= BNX2_MISC_NEW_CORE_CTL_DMA_ENABLE;
REG_WR(bp, BNX2_MISC_NEW_CORE_CTL, val);
}
rc = bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT2 | BNX2_DRV_MSG_CODE_RESET,
0);
@ -4620,6 +4644,11 @@ bnx2_timer(unsigned long data)
bp->stats_blk->stat_FwRxDrop = REG_RD_IND(bp, BNX2_FW_RX_DROP_COUNT);
/* workaround occasional corrupted counters */
if (CHIP_NUM(bp) == CHIP_NUM_5708 && bp->stats_ticks)
REG_WR(bp, BNX2_HC_COMMAND, bp->hc_cmd |
BNX2_HC_COMMAND_STATS_NOW);
if (bp->phy_flags & PHY_SERDES_FLAG) {
if (CHIP_NUM(bp) == CHIP_NUM_5706)
bnx2_5706_serdes_timer(bp);
@ -5417,6 +5446,10 @@ bnx2_set_coalesce(struct net_device *dev, struct ethtool_coalesce *coal)
0xff;
bp->stats_ticks = coal->stats_block_coalesce_usecs;
if (CHIP_NUM(bp) == CHIP_NUM_5708) {
if (bp->stats_ticks != 0 && bp->stats_ticks != USEC_PER_SEC)
bp->stats_ticks = USEC_PER_SEC;
}
if (bp->stats_ticks > 0xffff00) bp->stats_ticks = 0xffff00;
bp->stats_ticks &= 0xffff00;

View File

@ -1373,6 +1373,7 @@ struct l2_fhdr {
#define BNX2_MISC_NEW_CORE_CTL 0x000008c8
#define BNX2_MISC_NEW_CORE_CTL_LINK_HOLDOFF_SUCCESS (1L<<0)
#define BNX2_MISC_NEW_CORE_CTL_LINK_HOLDOFF_REQ (1L<<1)
#define BNX2_MISC_NEW_CORE_CTL_DMA_ENABLE (1L<<16)
#define BNX2_MISC_NEW_CORE_CTL_RESERVED_CMN (0x3fffL<<2)
#define BNX2_MISC_NEW_CORE_CTL_RESERVED_TC (0xffffL<<16)

View File

@ -3,6 +3,7 @@
#ifdef __KERNEL__
#include <linux/bitmap.h>
#include <linux/if.h>
#include <linux/netdevice.h>
#include <linux/rcupdate.h>
@ -10,28 +11,9 @@
struct ipv4_devconf
{
int accept_redirects;
int send_redirects;
int secure_redirects;
int shared_media;
int accept_source_route;
int rp_filter;
int proxy_arp;
int bootp_relay;
int log_martians;
int forwarding;
int mc_forwarding;
int tag;
int arp_filter;
int arp_announce;
int arp_ignore;
int arp_accept;
int medium_id;
int no_xfrm;
int no_policy;
int force_igmp_version;
int promote_secondaries;
void *sysctl;
int data[__NET_IPV4_CONF_MAX - 1];
DECLARE_BITMAP(state, __NET_IPV4_CONF_MAX - 1);
};
extern struct ipv4_devconf ipv4_devconf;
@ -60,30 +42,70 @@ struct in_device
struct rcu_head rcu_head;
};
#define IN_DEV_FORWARD(in_dev) ((in_dev)->cnf.forwarding)
#define IN_DEV_MFORWARD(in_dev) (ipv4_devconf.mc_forwarding && (in_dev)->cnf.mc_forwarding)
#define IN_DEV_RPFILTER(in_dev) (ipv4_devconf.rp_filter && (in_dev)->cnf.rp_filter)
#define IN_DEV_SOURCE_ROUTE(in_dev) (ipv4_devconf.accept_source_route && (in_dev)->cnf.accept_source_route)
#define IN_DEV_BOOTP_RELAY(in_dev) (ipv4_devconf.bootp_relay && (in_dev)->cnf.bootp_relay)
#define IPV4_DEVCONF(cnf, attr) ((cnf).data[NET_IPV4_CONF_ ## attr - 1])
#define IPV4_DEVCONF_ALL(attr) IPV4_DEVCONF(ipv4_devconf, attr)
#define IN_DEV_LOG_MARTIANS(in_dev) (ipv4_devconf.log_martians || (in_dev)->cnf.log_martians)
#define IN_DEV_PROXY_ARP(in_dev) (ipv4_devconf.proxy_arp || (in_dev)->cnf.proxy_arp)
#define IN_DEV_SHARED_MEDIA(in_dev) (ipv4_devconf.shared_media || (in_dev)->cnf.shared_media)
#define IN_DEV_TX_REDIRECTS(in_dev) (ipv4_devconf.send_redirects || (in_dev)->cnf.send_redirects)
#define IN_DEV_SEC_REDIRECTS(in_dev) (ipv4_devconf.secure_redirects || (in_dev)->cnf.secure_redirects)
#define IN_DEV_IDTAG(in_dev) ((in_dev)->cnf.tag)
#define IN_DEV_MEDIUM_ID(in_dev) ((in_dev)->cnf.medium_id)
#define IN_DEV_PROMOTE_SECONDARIES(in_dev) (ipv4_devconf.promote_secondaries || (in_dev)->cnf.promote_secondaries)
static inline int ipv4_devconf_get(struct in_device *in_dev, int index)
{
index--;
return in_dev->cnf.data[index];
}
static inline void ipv4_devconf_set(struct in_device *in_dev, int index,
int val)
{
index--;
set_bit(index, in_dev->cnf.state);
in_dev->cnf.data[index] = val;
}
static inline void ipv4_devconf_setall(struct in_device *in_dev)
{
bitmap_fill(in_dev->cnf.state, __NET_IPV4_CONF_MAX - 1);
}
#define IN_DEV_CONF_GET(in_dev, attr) \
ipv4_devconf_get((in_dev), NET_IPV4_CONF_ ## attr)
#define IN_DEV_CONF_SET(in_dev, attr, val) \
ipv4_devconf_set((in_dev), NET_IPV4_CONF_ ## attr, (val))
#define IN_DEV_ANDCONF(in_dev, attr) \
(IPV4_DEVCONF_ALL(attr) && IN_DEV_CONF_GET((in_dev), attr))
#define IN_DEV_ORCONF(in_dev, attr) \
(IPV4_DEVCONF_ALL(attr) || IN_DEV_CONF_GET((in_dev), attr))
#define IN_DEV_MAXCONF(in_dev, attr) \
(max(IPV4_DEVCONF_ALL(attr), IN_DEV_CONF_GET((in_dev), attr)))
#define IN_DEV_FORWARD(in_dev) IN_DEV_CONF_GET((in_dev), FORWARDING)
#define IN_DEV_MFORWARD(in_dev) (IPV4_DEVCONF_ALL(MC_FORWARDING) && \
IPV4_DEVCONF((in_dev)->cnf, \
MC_FORWARDING))
#define IN_DEV_RPFILTER(in_dev) IN_DEV_ANDCONF((in_dev), RP_FILTER)
#define IN_DEV_SOURCE_ROUTE(in_dev) IN_DEV_ANDCONF((in_dev), \
ACCEPT_SOURCE_ROUTE)
#define IN_DEV_BOOTP_RELAY(in_dev) IN_DEV_ANDCONF((in_dev), BOOTP_RELAY)
#define IN_DEV_LOG_MARTIANS(in_dev) IN_DEV_ORCONF((in_dev), LOG_MARTIANS)
#define IN_DEV_PROXY_ARP(in_dev) IN_DEV_ORCONF((in_dev), PROXY_ARP)
#define IN_DEV_SHARED_MEDIA(in_dev) IN_DEV_ORCONF((in_dev), SHARED_MEDIA)
#define IN_DEV_TX_REDIRECTS(in_dev) IN_DEV_ORCONF((in_dev), SEND_REDIRECTS)
#define IN_DEV_SEC_REDIRECTS(in_dev) IN_DEV_ORCONF((in_dev), \
SECURE_REDIRECTS)
#define IN_DEV_IDTAG(in_dev) IN_DEV_CONF_GET(in_dev, TAG)
#define IN_DEV_MEDIUM_ID(in_dev) IN_DEV_CONF_GET(in_dev, MEDIUM_ID)
#define IN_DEV_PROMOTE_SECONDARIES(in_dev) \
IN_DEV_ORCONF((in_dev), \
PROMOTE_SECONDARIES)
#define IN_DEV_RX_REDIRECTS(in_dev) \
((IN_DEV_FORWARD(in_dev) && \
(ipv4_devconf.accept_redirects && (in_dev)->cnf.accept_redirects)) \
IN_DEV_ANDCONF((in_dev), ACCEPT_REDIRECTS)) \
|| (!IN_DEV_FORWARD(in_dev) && \
(ipv4_devconf.accept_redirects || (in_dev)->cnf.accept_redirects)))
IN_DEV_ORCONF((in_dev), ACCEPT_REDIRECTS)))
#define IN_DEV_ARPFILTER(in_dev) (ipv4_devconf.arp_filter || (in_dev)->cnf.arp_filter)
#define IN_DEV_ARP_ANNOUNCE(in_dev) (max(ipv4_devconf.arp_announce, (in_dev)->cnf.arp_announce))
#define IN_DEV_ARP_IGNORE(in_dev) (max(ipv4_devconf.arp_ignore, (in_dev)->cnf.arp_ignore))
#define IN_DEV_ARPFILTER(in_dev) IN_DEV_ORCONF((in_dev), ARPFILTER)
#define IN_DEV_ARP_ANNOUNCE(in_dev) IN_DEV_MAXCONF((in_dev), ARP_ANNOUNCE)
#define IN_DEV_ARP_IGNORE(in_dev) IN_DEV_MAXCONF((in_dev), ARP_IGNORE)
struct in_ifaddr
{
@ -108,7 +130,6 @@ extern struct net_device *ip_dev_find(__be32 addr);
extern int inet_addr_onlink(struct in_device *in_dev, __be32 a, __be32 b);
extern int devinet_ioctl(unsigned int cmd, void __user *);
extern void devinet_init(void);
extern struct in_device *inetdev_init(struct net_device *dev);
extern struct in_device *inetdev_by_index(int);
extern __be32 inet_select_addr(const struct net_device *dev, __be32 dst, int scope);
extern __be32 inet_confirm_addr(const struct net_device *dev, __be32 dst, __be32 local, int scope);

View File

@ -264,6 +264,26 @@ ipt_get_target(struct ipt_entry *e)
__ret; \
})
/* fn returns 0 to continue iteration */
#define IPT_ENTRY_ITERATE_CONTINUE(entries, size, n, fn, args...) \
({ \
unsigned int __i, __n; \
int __ret = 0; \
struct ipt_entry *__entry; \
\
for (__i = 0, __n = 0; __i < (size); \
__i += __entry->next_offset, __n++) { \
__entry = (void *)(entries) + __i; \
if (__n < n) \
continue; \
\
__ret = fn(__entry , ## args); \
if (__ret != 0) \
break; \
} \
__ret; \
})
/*
* Main firewall chains definitions and global var's definitions.
*/

View File

@ -63,7 +63,7 @@ enum rfkill_state {
* This structure represents a RF switch located on a network device.
*/
struct rfkill {
char *name;
const char *name;
enum rfkill_type type;
enum rfkill_state state;

View File

@ -64,7 +64,7 @@ struct fib_rules_ops
void (*flush_cache)(void);
int nlgroup;
struct nla_policy *policy;
const struct nla_policy *policy;
struct list_head *rules_list;
struct module *owner;
};

View File

@ -60,7 +60,7 @@ struct genl_ops
{
u8 cmd;
unsigned int flags;
struct nla_policy *policy;
const struct nla_policy *policy;
int (*doit)(struct sk_buff *skb,
struct genl_info *info);
int (*dumpit)(struct sk_buff *skb,

View File

@ -143,6 +143,7 @@ struct ip_reply_arg {
__wsum csum;
int csumoffset; /* u16 offset of csum in iov[0].iov_base */
/* -1 if not needed */
int bound_dev_if;
};
void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *arg,

View File

@ -213,7 +213,7 @@ extern void fib_select_default(const struct flowi *flp, struct fib_result *res);
#endif /* CONFIG_IP_MULTIPLE_TABLES */
/* Exported by fib_frontend.c */
extern struct nla_policy rtm_ipv4_policy[];
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);

View File

@ -222,10 +222,10 @@ extern int nlmsg_notify(struct sock *sk, struct sk_buff *skb,
gfp_t flags);
extern int nla_validate(struct nlattr *head, int len, int maxtype,
struct nla_policy *policy);
const struct nla_policy *policy);
extern int nla_parse(struct nlattr *tb[], int maxtype,
struct nlattr *head, int len,
struct nla_policy *policy);
const struct nla_policy *policy);
extern struct nlattr * nla_find(struct nlattr *head, int len, int attrtype);
extern size_t nla_strlcpy(char *dst, const struct nlattr *nla,
size_t dstsize);
@ -360,7 +360,7 @@ static inline struct nlmsghdr *nlmsg_next(struct nlmsghdr *nlh, int *remaining)
*/
static inline int nlmsg_parse(struct nlmsghdr *nlh, int hdrlen,
struct nlattr *tb[], int maxtype,
struct nla_policy *policy)
const struct nla_policy *policy)
{
if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen))
return -EINVAL;
@ -392,7 +392,7 @@ static inline struct nlattr *nlmsg_find_attr(struct nlmsghdr *nlh,
* @policy: validation policy
*/
static inline int nlmsg_validate(struct nlmsghdr *nlh, int hdrlen, int maxtype,
struct nla_policy *policy)
const struct nla_policy *policy)
{
if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen))
return -EINVAL;
@ -729,7 +729,7 @@ static inline struct nlattr *nla_find_nested(struct nlattr *nla, int attrtype)
*/
static inline int nla_parse_nested(struct nlattr *tb[], int maxtype,
struct nlattr *nla,
struct nla_policy *policy)
const struct nla_policy *policy)
{
return nla_parse(tb, maxtype, nla_data(nla), nla_len(nla), policy);
}
@ -990,7 +990,7 @@ static inline int nla_nest_cancel(struct sk_buff *skb, struct nlattr *start)
* Returns 0 on success or a negative error code.
*/
static inline int nla_validate_nested(struct nlattr *start, int maxtype,
struct nla_policy *policy)
const struct nla_policy *policy)
{
return nla_validate(nla_data(start), nla_len(start), maxtype, policy);
}

View File

@ -119,16 +119,9 @@ static inline void udp_lib_close(struct sock *sk, long timeout)
}
struct udp_get_port_ops {
int (*saddr_cmp)(const struct sock *sk1, const struct sock *sk2);
int (*saddr_any)(const struct sock *sk);
unsigned int (*hash_port_and_rcv_saddr)(__u16 port,
const struct sock *sk);
};
/* net/ipv4/udp.c */
extern int udp_get_port(struct sock *sk, unsigned short snum,
const struct udp_get_port_ops *ops);
int (*saddr_cmp)(const struct sock *, const struct sock *));
extern void udp_err(struct sk_buff *, u32);
extern int udp_sendmsg(struct kiocb *iocb, struct sock *sk,

View File

@ -120,5 +120,5 @@ static inline __wsum udplite_csum_outgoing(struct sock *sk, struct sk_buff *skb)
extern void udplite4_register(void);
extern int udplite_get_port(struct sock *sk, unsigned short snum,
const struct udp_get_port_ops *ops);
int (*scmp)(const struct sock *, const struct sock *));
#endif /* _UDPLITE_H */

View File

@ -964,7 +964,7 @@ struct xfrmk_spdinfo {
extern struct xfrm_state *xfrm_find_acq_byseq(u32 seq);
extern int xfrm_state_delete(struct xfrm_state *x);
extern void xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info);
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);
@ -1020,13 +1020,13 @@ struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir,
struct xfrm_sec_ctx *ctx, int delete,
int *err);
struct xfrm_policy *xfrm_policy_byid(u8, int dir, u32 id, int delete, int *err);
void xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info);
int xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info);
u32 xfrm_get_acqseq(void);
void xfrm_alloc_spi(struct xfrm_state *x, __be32 minspi, __be32 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 void xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info);
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);

View File

@ -2577,7 +2577,7 @@ unsigned dev_get_flags(const struct net_device *dev)
int dev_change_flags(struct net_device *dev, unsigned flags)
{
int ret;
int ret, changes;
int old_flags = dev->flags;
/*
@ -2632,8 +2632,10 @@ int dev_change_flags(struct net_device *dev, unsigned flags)
dev_set_allmulti(dev, inc);
}
if (old_flags ^ dev->flags)
rtmsg_ifinfo(RTM_NEWLINK, dev, old_flags ^ dev->flags);
/* Exclude state transition flags, already notified */
changes = (old_flags ^ dev->flags) & ~(IFF_UP | IFF_RUNNING);
if (changes)
rtmsg_ifinfo(RTM_NEWLINK, dev, changes);
return ret;
}

View File

@ -111,13 +111,7 @@ out:
spin_unlock(&dst_lock);
}
static int dst_discard_in(struct sk_buff *skb)
{
kfree_skb(skb);
return 0;
}
static int dst_discard_out(struct sk_buff *skb)
static int dst_discard(struct sk_buff *skb)
{
kfree_skb(skb);
return 0;
@ -138,8 +132,7 @@ void * dst_alloc(struct dst_ops * ops)
dst->ops = ops;
dst->lastuse = jiffies;
dst->path = dst;
dst->input = dst_discard_in;
dst->output = dst_discard_out;
dst->input = dst->output = dst_discard;
#if RT_CACHE_DEBUG >= 2
atomic_inc(&dst_total);
#endif
@ -153,8 +146,7 @@ static void ___dst_free(struct dst_entry * dst)
protocol module is unloaded.
*/
if (dst->dev == NULL || !(dst->dev->flags&IFF_UP)) {
dst->input = dst_discard_in;
dst->output = dst_discard_out;
dst->input = dst->output = dst_discard;
}
dst->obsolete = 2;
}
@ -242,8 +234,7 @@ static inline void dst_ifdown(struct dst_entry *dst, struct net_device *dev,
return;
if (!unregister) {
dst->input = dst_discard_in;
dst->output = dst_discard_out;
dst->input = dst->output = dst_discard;
} else {
dst->dev = &loopback_dev;
dev_hold(&loopback_dev);

View File

@ -1761,7 +1761,7 @@ static inline struct neigh_parms *lookup_neigh_params(struct neigh_table *tbl,
return NULL;
}
static struct nla_policy nl_neightbl_policy[NDTA_MAX+1] __read_mostly = {
static const struct nla_policy nl_neightbl_policy[NDTA_MAX+1] = {
[NDTA_NAME] = { .type = NLA_STRING },
[NDTA_THRESH1] = { .type = NLA_U32 },
[NDTA_THRESH2] = { .type = NLA_U32 },
@ -1770,7 +1770,7 @@ static struct nla_policy nl_neightbl_policy[NDTA_MAX+1] __read_mostly = {
[NDTA_PARMS] = { .type = NLA_NESTED },
};
static struct nla_policy nl_ntbl_parm_policy[NDTPA_MAX+1] __read_mostly = {
static const struct nla_policy nl_ntbl_parm_policy[NDTPA_MAX+1] = {
[NDTPA_IFINDEX] = { .type = NLA_U32 },
[NDTPA_QUEUE_LEN] = { .type = NLA_U32 },
[NDTPA_PROXY_QLEN] = { .type = NLA_U32 },

View File

@ -551,7 +551,7 @@ cont:
return skb->len;
}
static struct nla_policy ifla_policy[IFLA_MAX+1] __read_mostly = {
static const struct nla_policy ifla_policy[IFLA_MAX+1] = {
[IFLA_IFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ-1 },
[IFLA_MAP] = { .len = sizeof(struct rtnl_link_ifmap) },
[IFLA_MTU] = { .type = NLA_U32 },
@ -580,7 +580,7 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
err = -EINVAL;
ifm = nlmsg_data(nlh);
if (ifm->ifi_index >= 0)
if (ifm->ifi_index > 0)
dev = dev_get_by_index(ifm->ifi_index);
else if (tb[IFLA_IFNAME])
dev = dev_get_by_name(ifname);
@ -672,7 +672,7 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
* name provided implies that a name change has been
* requested.
*/
if (ifm->ifi_index >= 0 && ifname[0]) {
if (ifm->ifi_index > 0 && ifname[0]) {
err = dev_change_name(dev, ifname);
if (err < 0)
goto errout_dev;
@ -740,7 +740,7 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
return err;
ifm = nlmsg_data(nlh);
if (ifm->ifi_index >= 0) {
if (ifm->ifi_index > 0) {
dev = dev_get_by_index(ifm->ifi_index);
if (dev == NULL)
return -ENODEV;

View File

@ -638,7 +638,7 @@ static struct dn_dev *dn_dev_by_index(int ifindex)
return dn_dev;
}
static struct nla_policy dn_ifa_policy[IFA_MAX+1] __read_mostly = {
static const struct nla_policy dn_ifa_policy[IFA_MAX+1] = {
[IFA_ADDRESS] = { .type = NLA_U16 },
[IFA_LOCAL] = { .type = NLA_U16 },
[IFA_LABEL] = { .type = NLA_STRING,

View File

@ -108,7 +108,7 @@ errout:
return err;
}
static struct nla_policy dn_fib_rule_policy[FRA_MAX+1] __read_mostly = {
static const struct nla_policy dn_fib_rule_policy[FRA_MAX+1] = {
FRA_GENERIC_POLICY,
};

View File

@ -877,7 +877,7 @@ static int arp_process(struct sk_buff *skb)
n = __neigh_lookup(&arp_tbl, &sip, dev, 0);
if (ipv4_devconf.arp_accept) {
if (IPV4_DEVCONF_ALL(ARP_ACCEPT)) {
/* Unsolicited ARP is not accepted by default.
It is possible, that this option should be enabled for some
devices (strip is candidate)
@ -987,11 +987,11 @@ static int arp_req_set(struct arpreq *r, struct net_device * dev)
return 0;
}
if (dev == NULL) {
ipv4_devconf.proxy_arp = 1;
IPV4_DEVCONF_ALL(PROXY_ARP) = 1;
return 0;
}
if (__in_dev_get_rtnl(dev)) {
__in_dev_get_rtnl(dev)->cnf.proxy_arp = 1;
IN_DEV_CONF_SET(__in_dev_get_rtnl(dev), PROXY_ARP, 1);
return 0;
}
return -ENXIO;
@ -1093,11 +1093,12 @@ static int arp_req_delete(struct arpreq *r, struct net_device * dev)
return pneigh_delete(&arp_tbl, &ip, dev);
if (mask == 0) {
if (dev == NULL) {
ipv4_devconf.proxy_arp = 0;
IPV4_DEVCONF_ALL(PROXY_ARP) = 0;
return 0;
}
if (__in_dev_get_rtnl(dev)) {
__in_dev_get_rtnl(dev)->cnf.proxy_arp = 0;
IN_DEV_CONF_SET(__in_dev_get_rtnl(dev),
PROXY_ARP, 0);
return 0;
}
return -ENXIO;

View File

@ -64,21 +64,27 @@
#include <net/rtnetlink.h>
struct ipv4_devconf ipv4_devconf = {
.accept_redirects = 1,
.send_redirects = 1,
.secure_redirects = 1,
.shared_media = 1,
.data = {
[NET_IPV4_CONF_ACCEPT_REDIRECTS - 1] = 1,
[NET_IPV4_CONF_SEND_REDIRECTS - 1] = 1,
[NET_IPV4_CONF_SECURE_REDIRECTS - 1] = 1,
[NET_IPV4_CONF_SHARED_MEDIA - 1] = 1,
},
};
static struct ipv4_devconf ipv4_devconf_dflt = {
.accept_redirects = 1,
.send_redirects = 1,
.secure_redirects = 1,
.shared_media = 1,
.accept_source_route = 1,
.data = {
[NET_IPV4_CONF_ACCEPT_REDIRECTS - 1] = 1,
[NET_IPV4_CONF_SEND_REDIRECTS - 1] = 1,
[NET_IPV4_CONF_SECURE_REDIRECTS - 1] = 1,
[NET_IPV4_CONF_SHARED_MEDIA - 1] = 1,
[NET_IPV4_CONF_ACCEPT_SOURCE_ROUTE - 1] = 1,
},
};
static struct nla_policy ifa_ipv4_policy[IFA_MAX+1] __read_mostly = {
#define IPV4_DEVCONF_DFLT(attr) IPV4_DEVCONF(ipv4_devconf_dflt, attr)
static const struct nla_policy ifa_ipv4_policy[IFA_MAX+1] = {
[IFA_LOCAL] = { .type = NLA_U32 },
[IFA_ADDRESS] = { .type = NLA_U32 },
[IFA_BROADCAST] = { .type = NLA_U32 },
@ -141,7 +147,7 @@ void in_dev_finish_destroy(struct in_device *idev)
}
}
struct in_device *inetdev_init(struct net_device *dev)
static struct in_device *inetdev_init(struct net_device *dev)
{
struct in_device *in_dev;
@ -399,12 +405,10 @@ static int inet_set_ifa(struct net_device *dev, struct in_ifaddr *ifa)
ASSERT_RTNL();
if (!in_dev) {
in_dev = inetdev_init(dev);
if (!in_dev) {
inet_free_ifa(ifa);
return -ENOBUFS;
}
inet_free_ifa(ifa);
return -ENOBUFS;
}
ipv4_devconf_setall(in_dev);
if (ifa->ifa_dev != in_dev) {
BUG_TRAP(!ifa->ifa_dev);
in_dev_hold(in_dev);
@ -514,13 +518,12 @@ static struct in_ifaddr *rtm_to_ifaddr(struct nlmsghdr *nlh)
in_dev = __in_dev_get_rtnl(dev);
if (in_dev == NULL) {
in_dev = inetdev_init(dev);
if (in_dev == NULL) {
err = -ENOBUFS;
goto errout;
}
err = -ENOBUFS;
goto errout;
}
ipv4_devconf_setall(in_dev);
ifa = inet_alloc_ifa();
if (ifa == NULL) {
/*
@ -1057,11 +1060,12 @@ static int inetdev_event(struct notifier_block *this, unsigned long event,
if (!in_dev) {
if (event == NETDEV_REGISTER) {
in_dev = inetdev_init(dev);
if (!in_dev)
panic("devinet: Failed to create loopback\n");
if (dev == &loopback_dev) {
in_dev->cnf.no_xfrm = 1;
in_dev->cnf.no_policy = 1;
if (!in_dev)
panic("devinet: "
"Failed to create loopback\n");
IN_DEV_CONF_SET(in_dev, NOXFRM, 1);
IN_DEV_CONF_SET(in_dev, NOPOLICY, 1);
}
}
goto out;
@ -1237,66 +1241,49 @@ errout:
#ifdef CONFIG_SYSCTL
void inet_forward_change(void)
static void devinet_copy_dflt_conf(int i)
{
struct net_device *dev;
int on = ipv4_devconf.forwarding;
ipv4_devconf.accept_redirects = !on;
ipv4_devconf_dflt.forwarding = on;
read_lock(&dev_base_lock);
for_each_netdev(dev) {
struct in_device *in_dev;
rcu_read_lock();
in_dev = __in_dev_get_rcu(dev);
if (in_dev)
in_dev->cnf.forwarding = on;
if (in_dev && !test_bit(i, in_dev->cnf.state))
in_dev->cnf.data[i] = ipv4_devconf_dflt.data[i];
rcu_read_unlock();
}
read_unlock(&dev_base_lock);
rt_cache_flush(0);
}
static int devinet_sysctl_forward(ctl_table *ctl, int write,
struct file* filp, void __user *buffer,
size_t *lenp, loff_t *ppos)
static int devinet_conf_proc(ctl_table *ctl, int write,
struct file* filp, void __user *buffer,
size_t *lenp, loff_t *ppos)
{
int *valp = ctl->data;
int val = *valp;
int ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
if (write && *valp != val) {
if (valp == &ipv4_devconf.forwarding)
inet_forward_change();
else if (valp != &ipv4_devconf_dflt.forwarding)
rt_cache_flush(0);
if (write) {
struct ipv4_devconf *cnf = ctl->extra1;
int i = (int *)ctl->data - cnf->data;
set_bit(i, cnf->state);
if (cnf == &ipv4_devconf_dflt)
devinet_copy_dflt_conf(i);
}
return ret;
}
int ipv4_doint_and_flush(ctl_table *ctl, int write,
struct file* filp, void __user *buffer,
size_t *lenp, loff_t *ppos)
{
int *valp = ctl->data;
int val = *valp;
int ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
if (write && *valp != val)
rt_cache_flush(0);
return ret;
}
int ipv4_doint_and_flush_strategy(ctl_table *table, int __user *name, int nlen,
void __user *oldval, size_t __user *oldlenp,
void __user *newval, size_t newlen)
static int devinet_conf_sysctl(ctl_table *table, int __user *name, int nlen,
void __user *oldval, size_t __user *oldlenp,
void __user *newval, size_t newlen)
{
struct ipv4_devconf *cnf;
int *valp = table->data;
int new;
int i;
if (!newval || !newlen)
return 0;
@ -1327,10 +1314,113 @@ int ipv4_doint_and_flush_strategy(ctl_table *table, int __user *name, int nlen,
}
*valp = new;
rt_cache_flush(0);
cnf = table->extra1;
i = (int *)table->data - cnf->data;
set_bit(i, cnf->state);
if (cnf == &ipv4_devconf_dflt)
devinet_copy_dflt_conf(i);
return 1;
}
void inet_forward_change(void)
{
struct net_device *dev;
int on = IPV4_DEVCONF_ALL(FORWARDING);
IPV4_DEVCONF_ALL(ACCEPT_REDIRECTS) = !on;
IPV4_DEVCONF_DFLT(FORWARDING) = on;
read_lock(&dev_base_lock);
for_each_netdev(dev) {
struct in_device *in_dev;
rcu_read_lock();
in_dev = __in_dev_get_rcu(dev);
if (in_dev)
IN_DEV_CONF_SET(in_dev, FORWARDING, on);
rcu_read_unlock();
}
read_unlock(&dev_base_lock);
rt_cache_flush(0);
}
static int devinet_sysctl_forward(ctl_table *ctl, int write,
struct file* filp, void __user *buffer,
size_t *lenp, loff_t *ppos)
{
int *valp = ctl->data;
int val = *valp;
int ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
if (write && *valp != val) {
if (valp == &IPV4_DEVCONF_ALL(FORWARDING))
inet_forward_change();
else if (valp != &IPV4_DEVCONF_DFLT(FORWARDING))
rt_cache_flush(0);
}
return ret;
}
int ipv4_doint_and_flush(ctl_table *ctl, int write,
struct file* filp, void __user *buffer,
size_t *lenp, loff_t *ppos)
{
int *valp = ctl->data;
int val = *valp;
int ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
if (write && *valp != val)
rt_cache_flush(0);
return ret;
}
int ipv4_doint_and_flush_strategy(ctl_table *table, int __user *name, int nlen,
void __user *oldval, size_t __user *oldlenp,
void __user *newval, size_t newlen)
{
int ret = devinet_conf_sysctl(table, name, nlen, oldval, oldlenp,
newval, newlen);
if (ret == 1)
rt_cache_flush(0);
return ret;
}
#define DEVINET_SYSCTL_ENTRY(attr, name, mval, proc, sysctl) \
{ \
.ctl_name = NET_IPV4_CONF_ ## attr, \
.procname = name, \
.data = ipv4_devconf.data + \
NET_IPV4_CONF_ ## attr - 1, \
.maxlen = sizeof(int), \
.mode = mval, \
.proc_handler = proc, \
.strategy = sysctl, \
.extra1 = &ipv4_devconf, \
}
#define DEVINET_SYSCTL_RW_ENTRY(attr, name) \
DEVINET_SYSCTL_ENTRY(attr, name, 0644, devinet_conf_proc, \
devinet_conf_sysctl)
#define DEVINET_SYSCTL_RO_ENTRY(attr, name) \
DEVINET_SYSCTL_ENTRY(attr, name, 0444, devinet_conf_proc, \
devinet_conf_sysctl)
#define DEVINET_SYSCTL_COMPLEX_ENTRY(attr, name, proc, sysctl) \
DEVINET_SYSCTL_ENTRY(attr, name, 0644, proc, sysctl)
#define DEVINET_SYSCTL_FLUSHING_ENTRY(attr, name) \
DEVINET_SYSCTL_COMPLEX_ENTRY(attr, name, ipv4_doint_and_flush, \
ipv4_doint_and_flush_strategy)
static struct devinet_sysctl_table {
struct ctl_table_header *sysctl_header;
@ -1341,178 +1431,34 @@ static struct devinet_sysctl_table {
ctl_table devinet_root_dir[2];
} devinet_sysctl = {
.devinet_vars = {
{
.ctl_name = NET_IPV4_CONF_FORWARDING,
.procname = "forwarding",
.data = &ipv4_devconf.forwarding,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &devinet_sysctl_forward,
},
{
.ctl_name = NET_IPV4_CONF_MC_FORWARDING,
.procname = "mc_forwarding",
.data = &ipv4_devconf.mc_forwarding,
.maxlen = sizeof(int),
.mode = 0444,
.proc_handler = &proc_dointvec,
},
{
.ctl_name = NET_IPV4_CONF_ACCEPT_REDIRECTS,
.procname = "accept_redirects",
.data = &ipv4_devconf.accept_redirects,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec,
},
{
.ctl_name = NET_IPV4_CONF_SECURE_REDIRECTS,
.procname = "secure_redirects",
.data = &ipv4_devconf.secure_redirects,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec,
},
{
.ctl_name = NET_IPV4_CONF_SHARED_MEDIA,
.procname = "shared_media",
.data = &ipv4_devconf.shared_media,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec,
},
{
.ctl_name = NET_IPV4_CONF_RP_FILTER,
.procname = "rp_filter",
.data = &ipv4_devconf.rp_filter,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec,
},
{
.ctl_name = NET_IPV4_CONF_SEND_REDIRECTS,
.procname = "send_redirects",
.data = &ipv4_devconf.send_redirects,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec,
},
{
.ctl_name = NET_IPV4_CONF_ACCEPT_SOURCE_ROUTE,
.procname = "accept_source_route",
.data = &ipv4_devconf.accept_source_route,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec,
},
{
.ctl_name = NET_IPV4_CONF_PROXY_ARP,
.procname = "proxy_arp",
.data = &ipv4_devconf.proxy_arp,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec,
},
{
.ctl_name = NET_IPV4_CONF_MEDIUM_ID,
.procname = "medium_id",
.data = &ipv4_devconf.medium_id,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec,
},
{
.ctl_name = NET_IPV4_CONF_BOOTP_RELAY,
.procname = "bootp_relay",
.data = &ipv4_devconf.bootp_relay,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec,
},
{
.ctl_name = NET_IPV4_CONF_LOG_MARTIANS,
.procname = "log_martians",
.data = &ipv4_devconf.log_martians,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec,
},
{
.ctl_name = NET_IPV4_CONF_TAG,
.procname = "tag",
.data = &ipv4_devconf.tag,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec,
},
{
.ctl_name = NET_IPV4_CONF_ARPFILTER,
.procname = "arp_filter",
.data = &ipv4_devconf.arp_filter,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec,
},
{
.ctl_name = NET_IPV4_CONF_ARP_ANNOUNCE,
.procname = "arp_announce",
.data = &ipv4_devconf.arp_announce,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec,
},
{
.ctl_name = NET_IPV4_CONF_ARP_IGNORE,
.procname = "arp_ignore",
.data = &ipv4_devconf.arp_ignore,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec,
},
{
.ctl_name = NET_IPV4_CONF_ARP_ACCEPT,
.procname = "arp_accept",
.data = &ipv4_devconf.arp_accept,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec,
},
{
.ctl_name = NET_IPV4_CONF_NOXFRM,
.procname = "disable_xfrm",
.data = &ipv4_devconf.no_xfrm,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &ipv4_doint_and_flush,
.strategy = &ipv4_doint_and_flush_strategy,
},
{
.ctl_name = NET_IPV4_CONF_NOPOLICY,
.procname = "disable_policy",
.data = &ipv4_devconf.no_policy,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &ipv4_doint_and_flush,
.strategy = &ipv4_doint_and_flush_strategy,
},
{
.ctl_name = NET_IPV4_CONF_FORCE_IGMP_VERSION,
.procname = "force_igmp_version",
.data = &ipv4_devconf.force_igmp_version,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &ipv4_doint_and_flush,
.strategy = &ipv4_doint_and_flush_strategy,
},
{
.ctl_name = NET_IPV4_CONF_PROMOTE_SECONDARIES,
.procname = "promote_secondaries",
.data = &ipv4_devconf.promote_secondaries,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &ipv4_doint_and_flush,
.strategy = &ipv4_doint_and_flush_strategy,
},
DEVINET_SYSCTL_COMPLEX_ENTRY(FORWARDING, "forwarding",
devinet_sysctl_forward,
devinet_conf_sysctl),
DEVINET_SYSCTL_RO_ENTRY(MC_FORWARDING, "mc_forwarding"),
DEVINET_SYSCTL_RW_ENTRY(ACCEPT_REDIRECTS, "accept_redirects"),
DEVINET_SYSCTL_RW_ENTRY(SECURE_REDIRECTS, "secure_redirects"),
DEVINET_SYSCTL_RW_ENTRY(SHARED_MEDIA, "shared_media"),
DEVINET_SYSCTL_RW_ENTRY(RP_FILTER, "rp_filter"),
DEVINET_SYSCTL_RW_ENTRY(SEND_REDIRECTS, "send_redirects"),
DEVINET_SYSCTL_RW_ENTRY(ACCEPT_SOURCE_ROUTE,
"accept_source_route"),
DEVINET_SYSCTL_RW_ENTRY(PROXY_ARP, "proxy_arp"),
DEVINET_SYSCTL_RW_ENTRY(MEDIUM_ID, "medium_id"),
DEVINET_SYSCTL_RW_ENTRY(BOOTP_RELAY, "bootp_relay"),
DEVINET_SYSCTL_RW_ENTRY(LOG_MARTIANS, "log_martians"),
DEVINET_SYSCTL_RW_ENTRY(TAG, "tag"),
DEVINET_SYSCTL_RW_ENTRY(ARPFILTER, "arp_filter"),
DEVINET_SYSCTL_RW_ENTRY(ARP_ANNOUNCE, "arp_announce"),
DEVINET_SYSCTL_RW_ENTRY(ARP_IGNORE, "arp_ignore"),
DEVINET_SYSCTL_RW_ENTRY(ARP_ACCEPT, "arp_accept"),
DEVINET_SYSCTL_FLUSHING_ENTRY(NOXFRM, "disable_xfrm"),
DEVINET_SYSCTL_FLUSHING_ENTRY(NOPOLICY, "disable_policy"),
DEVINET_SYSCTL_FLUSHING_ENTRY(FORCE_IGMP_VERSION,
"force_igmp_version"),
DEVINET_SYSCTL_FLUSHING_ENTRY(PROMOTE_SECONDARIES,
"promote_secondaries"),
},
.devinet_dev = {
{
@ -1561,6 +1507,7 @@ static void devinet_sysctl_register(struct in_device *in_dev,
return;
for (i = 0; i < ARRAY_SIZE(t->devinet_vars) - 1; i++) {
t->devinet_vars[i].data += (char *)p - (char *)&ipv4_devconf;
t->devinet_vars[i].extra1 = p;
}
if (dev) {

View File

@ -441,7 +441,7 @@ int ip_rt_ioctl(unsigned int cmd, void __user *arg)
return -EINVAL;
}
struct nla_policy rtm_ipv4_policy[RTA_MAX+1] __read_mostly = {
const struct nla_policy rtm_ipv4_policy[RTA_MAX+1] = {
[RTA_DST] = { .type = NLA_U32 },
[RTA_SRC] = { .type = NLA_U32 },
[RTA_IIF] = { .type = NLA_U32 },

View File

@ -169,7 +169,7 @@ static struct fib_table *fib_empty_table(void)
return NULL;
}
static struct nla_policy fib4_rule_policy[FRA_MAX+1] __read_mostly = {
static const struct nla_policy fib4_rule_policy[FRA_MAX+1] = {
FRA_GENERIC_POLICY,
[FRA_FLOW] = { .type = NLA_U32 },
};

View File

@ -128,14 +128,16 @@
* contradict to specs provided this delay is small enough.
*/
#define IGMP_V1_SEEN(in_dev) (ipv4_devconf.force_igmp_version == 1 || \
(in_dev)->cnf.force_igmp_version == 1 || \
((in_dev)->mr_v1_seen && \
time_before(jiffies, (in_dev)->mr_v1_seen)))
#define IGMP_V2_SEEN(in_dev) (ipv4_devconf.force_igmp_version == 2 || \
(in_dev)->cnf.force_igmp_version == 2 || \
((in_dev)->mr_v2_seen && \
time_before(jiffies, (in_dev)->mr_v2_seen)))
#define IGMP_V1_SEEN(in_dev) \
(IPV4_DEVCONF_ALL(FORCE_IGMP_VERSION) == 1 || \
IN_DEV_CONF_GET((in_dev), FORCE_IGMP_VERSION) == 1 || \
((in_dev)->mr_v1_seen && \
time_before(jiffies, (in_dev)->mr_v1_seen)))
#define IGMP_V2_SEEN(in_dev) \
(IPV4_DEVCONF_ALL(FORCE_IGMP_VERSION) == 2 || \
IN_DEV_CONF_GET((in_dev), FORCE_IGMP_VERSION) == 2 || \
((in_dev)->mr_v2_seen && \
time_before(jiffies, (in_dev)->mr_v2_seen)))
static void igmpv3_add_delrec(struct in_device *in_dev, struct ip_mc_list *im);
static void igmpv3_del_delrec(struct in_device *in_dev, __be32 multiaddr);

View File

@ -1352,7 +1352,8 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar
}
{
struct flowi fl = { .nl_u = { .ip4_u =
struct flowi fl = { .oif = arg->bound_dev_if,
.nl_u = { .ip4_u =
{ .daddr = daddr,
.saddr = rt->rt_spec_dst,
.tos = RT_TOS(ip_hdr(skb)->tos) } },
@ -1376,6 +1377,7 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar
inet->tos = ip_hdr(skb)->tos;
sk->sk_priority = skb->priority;
sk->sk_protocol = ip_hdr(skb)->protocol;
sk->sk_bound_dev_if = arg->bound_dev_if;
ip_append_data(sk, ip_reply_glue_bits, arg->iov->iov_base, len, 0,
&ipc, rt, MSG_DONTWAIT);
if ((skb = skb_peek(&sk->sk_write_queue)) != NULL) {

View File

@ -152,9 +152,11 @@ struct net_device *ipmr_new_tunnel(struct vifctl *v)
dev->flags |= IFF_MULTICAST;
in_dev = __in_dev_get_rtnl(dev);
if (in_dev == NULL && (in_dev = inetdev_init(dev)) == NULL)
if (in_dev == NULL)
goto failure;
in_dev->cnf.rp_filter = 0;
ipv4_devconf_setall(in_dev);
IPV4_DEVCONF(in_dev->cnf, RP_FILTER) = 0;
if (dev_open(dev))
goto failure;
@ -218,10 +220,15 @@ static struct net_device *ipmr_reg_vif(void)
}
dev->iflink = 0;
if ((in_dev = inetdev_init(dev)) == NULL)
rcu_read_lock();
if ((in_dev = __in_dev_get_rcu(dev)) == NULL) {
rcu_read_unlock();
goto failure;
}
in_dev->cnf.rp_filter = 0;
ipv4_devconf_setall(in_dev);
IPV4_DEVCONF(in_dev->cnf, RP_FILTER) = 0;
rcu_read_unlock();
if (dev_open(dev))
goto failure;
@ -281,7 +288,7 @@ static int vif_delete(int vifi)
dev_set_allmulti(dev, -1);
if ((in_dev = __in_dev_get_rtnl(dev)) != NULL) {
in_dev->cnf.mc_forwarding--;
IPV4_DEVCONF(in_dev->cnf, MC_FORWARDING)--;
ip_rt_multicast_event(in_dev);
}
@ -426,7 +433,7 @@ static int vif_add(struct vifctl *vifc, int mrtsock)
if ((in_dev = __in_dev_get_rtnl(dev)) == NULL)
return -EADDRNOTAVAIL;
in_dev->cnf.mc_forwarding++;
IPV4_DEVCONF(in_dev->cnf, MC_FORWARDING)++;
dev_set_allmulti(dev, +1);
ip_rt_multicast_event(in_dev);
@ -841,7 +848,7 @@ static void mrtsock_destruct(struct sock *sk)
{
rtnl_lock();
if (sk == mroute_socket) {
ipv4_devconf.mc_forwarding--;
IPV4_DEVCONF_ALL(MC_FORWARDING)--;
write_lock_bh(&mrt_lock);
mroute_socket=NULL;
@ -890,7 +897,7 @@ int ip_mroute_setsockopt(struct sock *sk,int optname,char __user *optval,int opt
mroute_socket=sk;
write_unlock_bh(&mrt_lock);
ipv4_devconf.mc_forwarding++;
IPV4_DEVCONF_ALL(MC_FORWARDING)++;
}
rtnl_unlock();
return ret;

View File

@ -499,7 +499,8 @@ check_entry(struct ipt_entry *e, const char *name)
}
static inline int check_match(struct ipt_entry_match *m, const char *name,
const struct ipt_ip *ip, unsigned int hookmask)
const struct ipt_ip *ip, unsigned int hookmask,
unsigned int *i)
{
struct xt_match *match;
int ret;
@ -515,6 +516,8 @@ static inline int check_match(struct ipt_entry_match *m, const char *name,
m->u.kernel.match->name);
ret = -EINVAL;
}
if (!ret)
(*i)++;
return ret;
}
@ -537,11 +540,10 @@ find_check_match(struct ipt_entry_match *m,
}
m->u.kernel.match = match;
ret = check_match(m, name, ip, hookmask);
ret = check_match(m, name, ip, hookmask, i);
if (ret)
goto err;
(*i)++;
return 0;
err:
module_put(m->u.kernel.match->me);
@ -1425,7 +1427,7 @@ out:
}
static inline int
compat_check_calc_match(struct ipt_entry_match *m,
compat_find_calc_match(struct ipt_entry_match *m,
const char *name,
const struct ipt_ip *ip,
unsigned int hookmask,
@ -1448,6 +1450,31 @@ compat_check_calc_match(struct ipt_entry_match *m,
return 0;
}
static inline int
compat_release_match(struct ipt_entry_match *m, unsigned int *i)
{
if (i && (*i)-- == 0)
return 1;
module_put(m->u.kernel.match->me);
return 0;
}
static inline int
compat_release_entry(struct ipt_entry *e, unsigned int *i)
{
struct ipt_entry_target *t;
if (i && (*i)-- == 0)
return 1;
/* Cleanup all matches */
IPT_MATCH_ITERATE(e, compat_release_match, NULL);
t = ipt_get_target(e);
module_put(t->u.kernel.target->me);
return 0;
}
static inline int
check_compat_entry_size_and_hooks(struct ipt_entry *e,
struct xt_table_info *newinfo,
@ -1485,10 +1512,10 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e,
off = 0;
entry_offset = (void *)e - (void *)base;
j = 0;
ret = IPT_MATCH_ITERATE(e, compat_check_calc_match, name, &e->ip,
ret = IPT_MATCH_ITERATE(e, compat_find_calc_match, name, &e->ip,
e->comefrom, &off, &j);
if (ret != 0)
goto cleanup_matches;
goto release_matches;
t = ipt_get_target(e);
target = try_then_request_module(xt_find_target(AF_INET,
@ -1499,7 +1526,7 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e,
duprintf("check_compat_entry_size_and_hooks: `%s' not found\n",
t->u.user.name);
ret = target ? PTR_ERR(target) : -ENOENT;
goto cleanup_matches;
goto release_matches;
}
t->u.kernel.target = target;
@ -1526,8 +1553,8 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e,
out:
module_put(t->u.kernel.target->me);
cleanup_matches:
IPT_MATCH_ITERATE(e, cleanup_match, &j);
release_matches:
IPT_MATCH_ITERATE(e, compat_release_match, &j);
return ret;
}
@ -1574,15 +1601,26 @@ static int compat_copy_entry_from_user(struct ipt_entry *e, void **dstptr,
return ret;
}
static inline int compat_check_entry(struct ipt_entry *e, const char *name)
static inline int compat_check_entry(struct ipt_entry *e, const char *name,
unsigned int *i)
{
int ret;
int j, ret;
ret = IPT_MATCH_ITERATE(e, check_match, name, &e->ip, e->comefrom);
j = 0;
ret = IPT_MATCH_ITERATE(e, check_match, name, &e->ip, e->comefrom, &j);
if (ret)
return ret;
goto cleanup_matches;
return check_target(e, name);
ret = check_target(e, name);
if (ret)
goto cleanup_matches;
(*i)++;
return 0;
cleanup_matches:
IPT_MATCH_ITERATE(e, cleanup_match, &j);
return ret;
}
static int
@ -1673,10 +1711,17 @@ translate_compat_table(const char *name,
if (!mark_source_chains(newinfo, valid_hooks, entry1))
goto free_newinfo;
i = 0;
ret = IPT_ENTRY_ITERATE(entry1, newinfo->size, compat_check_entry,
name);
if (ret)
goto free_newinfo;
name, &i);
if (ret) {
j -= i;
IPT_ENTRY_ITERATE_CONTINUE(entry1, newinfo->size, i,
compat_release_entry, &j);
IPT_ENTRY_ITERATE(entry1, newinfo->size, cleanup_entry, &i);
xt_free_table_info(newinfo);
return ret;
}
/* And one copy for every other CPU */
for_each_possible_cpu(i)
@ -1691,7 +1736,7 @@ translate_compat_table(const char *name,
free_newinfo:
xt_free_table_info(newinfo);
out:
IPT_ENTRY_ITERATE(entry0, total_size, cleanup_entry, &j);
IPT_ENTRY_ITERATE(entry0, total_size, compat_release_entry, &j);
return ret;
out_unlock:
compat_flush_offsets();

View File

@ -133,6 +133,7 @@ static unsigned int ipv4_conntrack_help(unsigned int hooknum,
struct nf_conn *ct;
enum ip_conntrack_info ctinfo;
struct nf_conn_help *help;
struct nf_conntrack_helper *helper;
/* This is where we call the helper: as the packet goes out. */
ct = nf_ct_get(*pskb, &ctinfo);
@ -140,12 +141,14 @@ static unsigned int ipv4_conntrack_help(unsigned int hooknum,
return NF_ACCEPT;
help = nfct_help(ct);
if (!help || !help->helper)
if (!help)
return NF_ACCEPT;
return help->helper->help(pskb,
skb_network_offset(*pskb) + ip_hdrlen(*pskb),
ct, ctinfo);
/* rcu_read_lock()ed by nf_hook_slow */
helper = rcu_dereference(help->helper);
if (!helper)
return NF_ACCEPT;
return helper->help(pskb, skb_network_offset(*pskb) + ip_hdrlen(*pskb),
ct, ctinfo);
}
static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,

View File

@ -260,7 +260,7 @@ static int snmp_seq_show(struct seq_file *seq, void *v)
seq_printf(seq, " %s", snmp4_ipstats_list[i].name);
seq_printf(seq, "\nIp: %d %d",
ipv4_devconf.forwarding ? 1 : 2, sysctl_ip_default_ttl);
IPV4_DEVCONF_ALL(FORWARDING) ? 1 : 2, sysctl_ip_default_ttl);
for (i = 0; snmp4_ipstats_list[i].name != NULL; i++)
seq_printf(seq, " %lu",

View File

@ -1636,7 +1636,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
atomic_set(&rth->u.dst.__refcnt, 1);
rth->u.dst.flags= DST_HOST;
if (in_dev->cnf.no_policy)
if (IN_DEV_CONF_GET(in_dev, NOPOLICY))
rth->u.dst.flags |= DST_NOPOLICY;
rth->fl.fl4_dst = daddr;
rth->rt_dst = daddr;
@ -1778,9 +1778,9 @@ static inline int __mkroute_input(struct sk_buff *skb,
if (res->fi->fib_nhs > 1)
rth->u.dst.flags |= DST_BALANCED;
#endif
if (in_dev->cnf.no_policy)
if (IN_DEV_CONF_GET(in_dev, NOPOLICY))
rth->u.dst.flags |= DST_NOPOLICY;
if (out_dev->cnf.no_xfrm)
if (IN_DEV_CONF_GET(out_dev, NOXFRM))
rth->u.dst.flags |= DST_NOXFRM;
rth->fl.fl4_dst = daddr;
rth->rt_dst = daddr;
@ -2021,7 +2021,7 @@ local_input:
atomic_set(&rth->u.dst.__refcnt, 1);
rth->u.dst.flags= DST_HOST;
if (in_dev->cnf.no_policy)
if (IN_DEV_CONF_GET(in_dev, NOPOLICY))
rth->u.dst.flags |= DST_NOPOLICY;
rth->fl.fl4_dst = daddr;
rth->rt_dst = daddr;
@ -2218,9 +2218,9 @@ static inline int __mkroute_output(struct rtable **result,
rth->u.dst.flags |= DST_BALANCED;
}
#endif
if (in_dev->cnf.no_xfrm)
if (IN_DEV_CONF_GET(in_dev, NOXFRM))
rth->u.dst.flags |= DST_NOXFRM;
if (in_dev->cnf.no_policy)
if (IN_DEV_CONF_GET(in_dev, NOPOLICY))
rth->u.dst.flags |= DST_NOPOLICY;
rth->fl.fl4_dst = oldflp->fl4_dst;
@ -2759,7 +2759,7 @@ static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
__be32 dst = rt->rt_dst;
if (MULTICAST(dst) && !LOCAL_MCAST(dst) &&
ipv4_devconf.mc_forwarding) {
IPV4_DEVCONF_ALL(MC_FORWARDING)) {
int err = ipmr_get_route(skb, r, nowait);
if (err <= 0) {
if (!nowait) {

View File

@ -37,12 +37,12 @@ static
int ipv4_sysctl_forward(ctl_table *ctl, int write, struct file * filp,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
int val = ipv4_devconf.forwarding;
int val = IPV4_DEVCONF_ALL(FORWARDING);
int ret;
ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
if (write && ipv4_devconf.forwarding != val)
if (write && IPV4_DEVCONF_ALL(FORWARDING) != val)
inet_forward_change();
return ret;
@ -222,7 +222,7 @@ ctl_table ipv4_table[] = {
{
.ctl_name = NET_IPV4_FORWARD,
.procname = "ip_forward",
.data = &ipv4_devconf.forwarding,
.data = &IPV4_DEVCONF_ALL(FORWARDING),
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &ipv4_sysctl_forward,

View File

@ -705,6 +705,8 @@ static void tcp_v4_send_ack(struct tcp_timewait_sock *twsk,
ip_hdr(skb)->saddr, /* XXX */
arg.iov[0].iov_len, IPPROTO_TCP, 0);
arg.csumoffset = offsetof(struct tcphdr, check) / 2;
if (twsk)
arg.bound_dev_if = twsk->tw_sk.tw_bound_dev_if;
ip_send_reply(tcp_socket->sk, skb, &arg, arg.iov[0].iov_len);

View File

@ -62,6 +62,9 @@ struct {
* Print to log with timestamps.
* FIXME: causes an extra copy
*/
static void printl(const char *fmt, ...)
__attribute__ ((format (printf, 1, 2)));
static void printl(const char *fmt, ...)
{
va_list args;
@ -80,8 +83,7 @@ static void printl(const char *fmt, ...)
kfifo_put(tcpw.fifo, tbuf, len);
wake_up(&tcpw.wait);
} __attribute__ ((format (printf, 1, 2)));
}
/*
* Hook inserted to be called before each receive packet.

View File

@ -292,9 +292,9 @@ static void tcp_retransmit_timer(struct sock *sk)
* we cannot allow such beasts to hang infinitely.
*/
#ifdef TCP_DEBUG
if (net_ratelimit()) {
if (1) {
struct inet_sock *inet = inet_sk(sk);
printk(KERN_DEBUG "TCP: Treason uncloaked! Peer %u.%u.%u.%u:%u/%u shrinks window %u:%u. Repaired.\n",
LIMIT_NETDEBUG(KERN_DEBUG "TCP: Treason uncloaked! Peer %u.%u.%u.%u:%u/%u shrinks window %u:%u. Repaired.\n",
NIPQUAD(inet->daddr), ntohs(inet->dport),
inet->num, tp->snd_una, tp->snd_nxt);
}

View File

@ -114,36 +114,14 @@ DEFINE_RWLOCK(udp_hash_lock);
static int udp_port_rover;
/*
* Note about this hash function :
* Typical use is probably daddr = 0, only dport is going to vary hash
*/
static inline unsigned int udp_hash_port(__u16 port)
{
return port;
}
static inline int __udp_lib_port_inuse(unsigned int hash, int port,
const struct sock *this_sk,
struct hlist_head udptable[],
const struct udp_get_port_ops *ops)
static inline int __udp_lib_lport_inuse(__u16 num, struct hlist_head udptable[])
{
struct sock *sk;
struct hlist_node *node;
struct inet_sock *inet;
sk_for_each(sk, node, &udptable[hash & (UDP_HTABLE_SIZE - 1)]) {
if (sk->sk_hash != hash)
continue;
inet = inet_sk(sk);
if (inet->num != port)
continue;
if (this_sk) {
if (ops->saddr_cmp(sk, this_sk))
return 1;
} else if (ops->saddr_any(sk))
sk_for_each(sk, node, &udptable[num & (UDP_HTABLE_SIZE - 1)])
if (sk->sk_hash == num)
return 1;
}
return 0;
}
@ -154,16 +132,16 @@ static inline int __udp_lib_port_inuse(unsigned int hash, int port,
* @snum: port number to look up
* @udptable: hash list table, must be of UDP_HTABLE_SIZE
* @port_rover: pointer to record of last unallocated port
* @ops: AF-dependent address operations
* @saddr_comp: AF-dependent comparison of bound local IP addresses
*/
int __udp_lib_get_port(struct sock *sk, unsigned short snum,
struct hlist_head udptable[], int *port_rover,
const struct udp_get_port_ops *ops)
int (*saddr_comp)(const struct sock *sk1,
const struct sock *sk2 ) )
{
struct hlist_node *node;
struct hlist_head *head;
struct sock *sk2;
unsigned int hash;
int error = 1;
write_lock_bh(&udp_hash_lock);
@ -178,8 +156,7 @@ int __udp_lib_get_port(struct sock *sk, unsigned short snum,
for (i = 0; i < UDP_HTABLE_SIZE; i++, result++) {
int size;
hash = ops->hash_port_and_rcv_saddr(result, sk);
head = &udptable[hash & (UDP_HTABLE_SIZE - 1)];
head = &udptable[result & (UDP_HTABLE_SIZE - 1)];
if (hlist_empty(head)) {
if (result > sysctl_local_port_range[1])
result = sysctl_local_port_range[0] +
@ -204,16 +181,7 @@ int __udp_lib_get_port(struct sock *sk, unsigned short snum,
result = sysctl_local_port_range[0]
+ ((result - sysctl_local_port_range[0]) &
(UDP_HTABLE_SIZE - 1));
hash = udp_hash_port(result);
if (__udp_lib_port_inuse(hash, result,
NULL, udptable, ops))
continue;
if (ops->saddr_any(sk))
break;
hash = ops->hash_port_and_rcv_saddr(result, sk);
if (! __udp_lib_port_inuse(hash, result,
sk, udptable, ops))
if (! __udp_lib_lport_inuse(result, udptable))
break;
}
if (i >= (1 << 16) / UDP_HTABLE_SIZE)
@ -221,40 +189,21 @@ int __udp_lib_get_port(struct sock *sk, unsigned short snum,
gotit:
*port_rover = snum = result;
} else {
hash = udp_hash_port(snum);
head = &udptable[hash & (UDP_HTABLE_SIZE - 1)];
head = &udptable[snum & (UDP_HTABLE_SIZE - 1)];
sk_for_each(sk2, node, head)
if (sk2->sk_hash == hash &&
sk2 != sk &&
inet_sk(sk2)->num == snum &&
(!sk2->sk_reuse || !sk->sk_reuse) &&
(!sk2->sk_bound_dev_if || !sk->sk_bound_dev_if ||
sk2->sk_bound_dev_if == sk->sk_bound_dev_if) &&
ops->saddr_cmp(sk, sk2))
if (sk2->sk_hash == snum &&
sk2 != sk &&
(!sk2->sk_reuse || !sk->sk_reuse) &&
(!sk2->sk_bound_dev_if || !sk->sk_bound_dev_if
|| sk2->sk_bound_dev_if == sk->sk_bound_dev_if) &&
(*saddr_comp)(sk, sk2) )
goto fail;
if (!ops->saddr_any(sk)) {
hash = ops->hash_port_and_rcv_saddr(snum, sk);
head = &udptable[hash & (UDP_HTABLE_SIZE - 1)];
sk_for_each(sk2, node, head)
if (sk2->sk_hash == hash &&
sk2 != sk &&
inet_sk(sk2)->num == snum &&
(!sk2->sk_reuse || !sk->sk_reuse) &&
(!sk2->sk_bound_dev_if ||
!sk->sk_bound_dev_if ||
sk2->sk_bound_dev_if ==
sk->sk_bound_dev_if) &&
ops->saddr_cmp(sk, sk2))
goto fail;
}
}
inet_sk(sk)->num = snum;
sk->sk_hash = hash;
sk->sk_hash = snum;
if (sk_unhashed(sk)) {
head = &udptable[hash & (UDP_HTABLE_SIZE - 1)];
head = &udptable[snum & (UDP_HTABLE_SIZE - 1)];
sk_add_node(sk, head);
sock_prot_inc_use(sk->sk_prot);
}
@ -265,12 +214,12 @@ fail:
}
int udp_get_port(struct sock *sk, unsigned short snum,
const struct udp_get_port_ops *ops)
int (*scmp)(const struct sock *, const struct sock *))
{
return __udp_lib_get_port(sk, snum, udp_hash, &udp_port_rover, ops);
return __udp_lib_get_port(sk, snum, udp_hash, &udp_port_rover, scmp);
}
static int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2)
int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2)
{
struct inet_sock *inet1 = inet_sk(sk1), *inet2 = inet_sk(sk2);
@ -279,33 +228,9 @@ static int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2)
inet1->rcv_saddr == inet2->rcv_saddr ));
}
static int ipv4_rcv_saddr_any(const struct sock *sk)
{
return !inet_sk(sk)->rcv_saddr;
}
static inline unsigned int ipv4_hash_port_and_addr(__u16 port, __be32 addr)
{
addr ^= addr >> 16;
addr ^= addr >> 8;
return port ^ addr;
}
static unsigned int ipv4_hash_port_and_rcv_saddr(__u16 port,
const struct sock *sk)
{
return ipv4_hash_port_and_addr(port, inet_sk(sk)->rcv_saddr);
}
const struct udp_get_port_ops udp_ipv4_ops = {
.saddr_cmp = ipv4_rcv_saddr_equal,
.saddr_any = ipv4_rcv_saddr_any,
.hash_port_and_rcv_saddr = ipv4_hash_port_and_rcv_saddr,
};
static inline int udp_v4_get_port(struct sock *sk, unsigned short snum)
{
return udp_get_port(sk, snum, &udp_ipv4_ops);
return udp_get_port(sk, snum, ipv4_rcv_saddr_equal);
}
/* UDP is nearly always wildcards out the wazoo, it makes no sense to try
@ -317,77 +242,63 @@ static struct sock *__udp4_lib_lookup(__be32 saddr, __be16 sport,
{
struct sock *sk, *result = NULL;
struct hlist_node *node;
unsigned int hash, hashwild;
int score, best = -1, hport = ntohs(dport);
hash = ipv4_hash_port_and_addr(hport, daddr);
hashwild = udp_hash_port(hport);
unsigned short hnum = ntohs(dport);
int badness = -1;
read_lock(&udp_hash_lock);
lookup:
sk_for_each(sk, node, &udptable[hash & (UDP_HTABLE_SIZE - 1)]) {
sk_for_each(sk, node, &udptable[hnum & (UDP_HTABLE_SIZE - 1)]) {
struct inet_sock *inet = inet_sk(sk);
if (sk->sk_hash != hash || ipv6_only_sock(sk) ||
inet->num != hport)
continue;
score = (sk->sk_family == PF_INET ? 1 : 0);
if (inet->rcv_saddr) {
if (inet->rcv_saddr != daddr)
continue;
score+=2;
}
if (inet->daddr) {
if (inet->daddr != saddr)
continue;
score+=2;
}
if (inet->dport) {
if (inet->dport != sport)
continue;
score+=2;
}
if (sk->sk_bound_dev_if) {
if (sk->sk_bound_dev_if != dif)
continue;
score+=2;
}
if (score == 9) {
result = sk;
goto found;
} else if (score > best) {
result = sk;
best = score;
if (sk->sk_hash == hnum && !ipv6_only_sock(sk)) {
int score = (sk->sk_family == PF_INET ? 1 : 0);
if (inet->rcv_saddr) {
if (inet->rcv_saddr != daddr)
continue;
score+=2;
}
if (inet->daddr) {
if (inet->daddr != saddr)
continue;
score+=2;
}
if (inet->dport) {
if (inet->dport != sport)
continue;
score+=2;
}
if (sk->sk_bound_dev_if) {
if (sk->sk_bound_dev_if != dif)
continue;
score+=2;
}
if (score == 9) {
result = sk;
break;
} else if (score > badness) {
result = sk;
badness = score;
}
}
}
if (hash != hashwild) {
hash = hashwild;
goto lookup;
}
found:
if (result)
sock_hold(result);
read_unlock(&udp_hash_lock);
return result;
}
static inline struct sock *udp_v4_mcast_next(struct sock *sk, unsigned int hnum,
int hport, __be32 loc_addr,
static inline struct sock *udp_v4_mcast_next(struct sock *sk,
__be16 loc_port, __be32 loc_addr,
__be16 rmt_port, __be32 rmt_addr,
int dif)
{
struct hlist_node *node;
struct sock *s = sk;
unsigned short hnum = ntohs(loc_port);
sk_for_each_from(s, node) {
struct inet_sock *inet = inet_sk(s);
if (s->sk_hash != hnum ||
inet->num != hport ||
(inet->daddr && inet->daddr != rmt_addr) ||
(inet->dport != rmt_port && inet->dport) ||
(inet->rcv_saddr && inet->rcv_saddr != loc_addr) ||
@ -1221,45 +1132,29 @@ static int __udp4_lib_mcast_deliver(struct sk_buff *skb,
__be32 saddr, __be32 daddr,
struct hlist_head udptable[])
{
struct sock *sk, *skw, *sknext;
struct sock *sk;
int dif;
int hport = ntohs(uh->dest);
unsigned int hash = ipv4_hash_port_and_addr(hport, daddr);
unsigned int hashwild = udp_hash_port(hport);
dif = skb->dev->ifindex;
read_lock(&udp_hash_lock);
sk = sk_head(&udptable[hash & (UDP_HTABLE_SIZE - 1)]);
skw = sk_head(&udptable[hashwild & (UDP_HTABLE_SIZE - 1)]);
sk = udp_v4_mcast_next(sk, hash, hport, daddr, uh->source, saddr, dif);
if (!sk) {
hash = hashwild;
sk = udp_v4_mcast_next(skw, hash, hport, daddr, uh->source,
saddr, dif);
}
sk = sk_head(&udptable[ntohs(uh->dest) & (UDP_HTABLE_SIZE - 1)]);
dif = skb->dev->ifindex;
sk = udp_v4_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif);
if (sk) {
struct sock *sknext = NULL;
do {
struct sk_buff *skb1 = skb;
sknext = udp_v4_mcast_next(sk_next(sk), hash, hport,
daddr, uh->source, saddr, dif);
if (!sknext && hash != hashwild) {
hash = hashwild;
sknext = udp_v4_mcast_next(skw, hash, hport,
daddr, uh->source, saddr, dif);
}
sknext = udp_v4_mcast_next(sk_next(sk), uh->dest, daddr,
uh->source, saddr, dif);
if (sknext)
skb1 = skb_clone(skb, GFP_ATOMIC);
if (skb1) {
int ret = udp_queue_rcv_skb(sk, skb1);
if (ret > 0)
/*
* we should probably re-process
* instead of dropping packets here.
*/
/* we should probably re-process instead
* of dropping packets here. */
kfree_skb(skb1);
}
sk = sknext;
@ -1346,7 +1241,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[],
return __udp4_lib_mcast_deliver(skb, uh, saddr, daddr, udptable);
sk = __udp4_lib_lookup(saddr, uh->source, daddr, uh->dest,
skb->dev->ifindex, udptable);
skb->dev->ifindex, udptable );
if (sk != NULL) {
int ret = udp_queue_rcv_skb(sk, skb);

View File

@ -5,14 +5,14 @@
#include <net/protocol.h>
#include <net/inet_common.h>
extern const struct udp_get_port_ops udp_ipv4_ops;
extern int __udp4_lib_rcv(struct sk_buff *, struct hlist_head [], int );
extern void __udp4_lib_err(struct sk_buff *, u32, struct hlist_head []);
extern int __udp_lib_get_port(struct sock *sk, unsigned short snum,
struct hlist_head udptable[], int *port_rover,
const struct udp_get_port_ops *ops);
int (*)(const struct sock*,const struct sock*));
extern int ipv4_rcv_saddr_equal(const struct sock *, const struct sock *);
extern int udp_setsockopt(struct sock *sk, int level, int optname,
char __user *optval, int optlen);

View File

@ -19,15 +19,14 @@ struct hlist_head udplite_hash[UDP_HTABLE_SIZE];
static int udplite_port_rover;
int udplite_get_port(struct sock *sk, unsigned short p,
const struct udp_get_port_ops *ops)
int (*c)(const struct sock *, const struct sock *))
{
return __udp_lib_get_port(sk, p, udplite_hash,
&udplite_port_rover, ops);
return __udp_lib_get_port(sk, p, udplite_hash, &udplite_port_rover, c);
}
static int udplite_v4_get_port(struct sock *sk, unsigned short snum)
{
return udplite_get_port(sk, snum, &udp_ipv4_ops);
return udplite_get_port(sk, snum, ipv4_rcv_saddr_equal);
}
static int udplite_rcv(struct sk_buff *skb)

View File

@ -2990,7 +2990,7 @@ static struct in6_addr *extract_addr(struct nlattr *addr, struct nlattr *local)
return pfx;
}
static struct nla_policy ifa_ipv6_policy[IFA_MAX+1] __read_mostly = {
static const struct nla_policy ifa_ipv6_policy[IFA_MAX+1] = {
[IFA_ADDRESS] = { .len = sizeof(struct in6_addr) },
[IFA_LOCAL] = { .len = sizeof(struct in6_addr) },
[IFA_CACHEINFO] = { .len = sizeof(struct ifa_cacheinfo) },

View File

@ -157,7 +157,7 @@ static int fib6_rule_match(struct fib_rule *rule, struct flowi *fl, int flags)
return 1;
}
static struct nla_policy fib6_rule_policy[FRA_MAX+1] __read_mostly = {
static const struct nla_policy fib6_rule_policy[FRA_MAX+1] = {
FRA_GENERIC_POLICY,
};

View File

@ -160,6 +160,7 @@ static unsigned int ipv6_confirm(unsigned int hooknum,
{
struct nf_conn *ct;
struct nf_conn_help *help;
struct nf_conntrack_helper *helper;
enum ip_conntrack_info ctinfo;
unsigned int ret, protoff;
unsigned int extoff = (u8 *)(ipv6_hdr(*pskb) + 1) - (*pskb)->data;
@ -172,7 +173,11 @@ static unsigned int ipv6_confirm(unsigned int hooknum,
goto out;
help = nfct_help(ct);
if (!help || !help->helper)
if (!help)
goto out;
/* rcu_read_lock()ed by nf_hook_slow */
helper = rcu_dereference(help->helper);
if (!helper)
goto out;
protoff = nf_ct_ipv6_skip_exthdr(*pskb, extoff, &pnum,
@ -182,7 +187,7 @@ static unsigned int ipv6_confirm(unsigned int hooknum,
return NF_ACCEPT;
}
ret = help->helper->help(pskb, protoff, ct, ctinfo);
ret = helper->help(pskb, protoff, ct, ctinfo);
if (ret != NF_ACCEPT)
return ret;
out:

View File

@ -1999,7 +1999,7 @@ void rt6_mtu_change(struct net_device *dev, unsigned mtu)
fib6_clean_all(rt6_mtu_change_route, 0, &arg);
}
static struct nla_policy rtm_ipv6_policy[RTA_MAX+1] __read_mostly = {
static const struct nla_policy rtm_ipv6_policy[RTA_MAX+1] = {
[RTA_GATEWAY] = { .len = sizeof(struct in6_addr) },
[RTA_OIF] = { .type = NLA_U32 },
[RTA_IIF] = { .type = NLA_U32 },

View File

@ -52,28 +52,9 @@
DEFINE_SNMP_STAT(struct udp_mib, udp_stats_in6) __read_mostly;
static int ipv6_rcv_saddr_any(const struct sock *sk)
{
struct ipv6_pinfo *np = inet6_sk(sk);
return ipv6_addr_any(&np->rcv_saddr);
}
static unsigned int ipv6_hash_port_and_rcv_saddr(__u16 port,
const struct sock *sk)
{
return port;
}
const struct udp_get_port_ops udp_ipv6_ops = {
.saddr_cmp = ipv6_rcv_saddr_equal,
.saddr_any = ipv6_rcv_saddr_any,
.hash_port_and_rcv_saddr = ipv6_hash_port_and_rcv_saddr,
};
static inline int udp_v6_get_port(struct sock *sk, unsigned short snum)
{
return udp_get_port(sk, snum, &udp_ipv6_ops);
return udp_get_port(sk, snum, ipv6_rcv_saddr_equal);
}
static struct sock *__udp6_lib_lookup(struct in6_addr *saddr, __be16 sport,

View File

@ -6,8 +6,6 @@
#include <net/addrconf.h>
#include <net/inet_common.h>
extern const struct udp_get_port_ops udp_ipv6_ops;
extern int __udp6_lib_rcv(struct sk_buff **, struct hlist_head [], int );
extern void __udp6_lib_err(struct sk_buff *, struct inet6_skb_parm *,
int , int , int , __be32 , struct hlist_head []);

View File

@ -37,7 +37,7 @@ static struct inet6_protocol udplitev6_protocol = {
static int udplite_v6_get_port(struct sock *sk, unsigned short snum)
{
return udplite_get_port(sk, snum, &udp_ipv6_ops);
return udplite_get_port(sk, snum, ipv6_rcv_saddr_equal);
}
struct proto udplitev6_prot = {

View File

@ -1682,6 +1682,7 @@ static int pfkey_flush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hd
unsigned proto;
struct km_event c;
struct xfrm_audit audit_info;
int err;
proto = pfkey_satype2proto(hdr->sadb_msg_satype);
if (proto == 0)
@ -1689,7 +1690,9 @@ static int pfkey_flush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hd
audit_info.loginuid = audit_get_loginuid(current->audit_context);
audit_info.secid = 0;
xfrm_state_flush(proto, &audit_info);
err = xfrm_state_flush(proto, &audit_info);
if (err)
return err;
c.data.proto = proto;
c.seq = hdr->sadb_msg_seq;
c.pid = hdr->sadb_msg_pid;
@ -2683,10 +2686,13 @@ static int pfkey_spdflush(struct sock *sk, struct sk_buff *skb, struct sadb_msg
{
struct km_event c;
struct xfrm_audit audit_info;
int err;
audit_info.loginuid = audit_get_loginuid(current->audit_context);
audit_info.secid = 0;
xfrm_policy_flush(XFRM_POLICY_TYPE_MAIN, &audit_info);
err = xfrm_policy_flush(XFRM_POLICY_TYPE_MAIN, &audit_info);
if (err)
return err;
c.data.type = XFRM_POLICY_TYPE_MAIN;
c.event = XFRM_MSG_FLUSHPOLICY;
c.pid = hdr->sadb_msg_pid;

View File

@ -208,13 +208,14 @@ static int __init nf_conntrack_amanda_init(void)
{
int ret, i;
ret = -ENOMEM;
for (i = 0; i < ARRAY_SIZE(search); i++) {
search[i].ts = textsearch_prepare(ts_algo, search[i].string,
search[i].len,
GFP_KERNEL, TS_AUTOLOAD);
if (search[i].ts == NULL)
if (IS_ERR(search[i].ts)) {
ret = PTR_ERR(search[i].ts);
goto err1;
}
}
ret = nf_conntrack_helper_register(&amanda_helper[0]);
if (ret < 0)
@ -227,10 +228,9 @@ static int __init nf_conntrack_amanda_init(void)
err2:
nf_conntrack_helper_unregister(&amanda_helper[0]);
err1:
for (; i >= 0; i--) {
if (search[i].ts)
textsearch_destroy(search[i].ts);
}
while (--i >= 0)
textsearch_destroy(search[i].ts);
return ret;
}

View File

@ -350,9 +350,15 @@ static void death_by_timeout(unsigned long ul_conntrack)
{
struct nf_conn *ct = (void *)ul_conntrack;
struct nf_conn_help *help = nfct_help(ct);
struct nf_conntrack_helper *helper;
if (help && help->helper && help->helper->destroy)
help->helper->destroy(ct);
if (help) {
rcu_read_lock();
helper = rcu_dereference(help->helper);
if (helper && helper->destroy)
helper->destroy(ct);
rcu_read_unlock();
}
write_lock_bh(&nf_conntrack_lock);
/* Inside lock so preempt is disabled on module removal path.
@ -661,6 +667,7 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
unsigned int dataoff)
{
struct nf_conn *conntrack;
struct nf_conn_help *help;
struct nf_conntrack_tuple repl_tuple;
struct nf_conntrack_expect *exp;
u_int32_t features = 0;
@ -691,6 +698,7 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
write_lock_bh(&nf_conntrack_lock);
exp = find_expectation(tuple);
help = nfct_help(conntrack);
if (exp) {
DEBUGP("conntrack: expectation arrives ct=%p exp=%p\n",
conntrack, exp);
@ -698,7 +706,7 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
__set_bit(IPS_EXPECTED_BIT, &conntrack->status);
conntrack->master = exp->master;
if (exp->helper)
nfct_help(conntrack)->helper = exp->helper;
rcu_assign_pointer(help->helper, exp->helper);
#ifdef CONFIG_NF_CONNTRACK_MARK
conntrack->mark = exp->master->mark;
#endif
@ -708,10 +716,11 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
nf_conntrack_get(&conntrack->master->ct_general);
NF_CT_STAT_INC(expect_new);
} else {
struct nf_conn_help *help = nfct_help(conntrack);
if (help)
help->helper = __nf_ct_helper_find(&repl_tuple);
if (help) {
/* not in hash table yet, so not strictly necessary */
rcu_assign_pointer(help->helper,
__nf_ct_helper_find(&repl_tuple));
}
NF_CT_STAT_INC(new);
}
@ -893,7 +902,8 @@ void nf_conntrack_alter_reply(struct nf_conn *ct,
helper = __nf_ct_helper_find(newreply);
if (helper)
memset(&help->help, 0, sizeof(help->help));
help->helper = helper;
/* not in hash table yet, so not strictly necessary */
rcu_assign_pointer(help->helper, helper);
}
write_unlock_bh(&nf_conntrack_lock);
}

View File

@ -337,6 +337,10 @@ int nf_conntrack_expect_related(struct nf_conntrack_expect *expect)
NF_CT_ASSERT(master_help);
write_lock_bh(&nf_conntrack_lock);
if (!master_help->helper) {
ret = -ESHUTDOWN;
goto out;
}
list_for_each_entry(i, &nf_conntrack_expect_list, list) {
if (expect_matches(i, expect)) {
/* Refresh timer: if it's dying, ignore.. */

View File

@ -93,7 +93,7 @@ static inline int unhelp(struct nf_conntrack_tuple_hash *i,
if (help && help->helper == me) {
nf_conntrack_event(IPCT_HELPER, ct);
help->helper = NULL;
rcu_assign_pointer(help->helper, NULL);
}
return 0;
}

View File

@ -171,21 +171,29 @@ ctnetlink_dump_helpinfo(struct sk_buff *skb, const struct nf_conn *ct)
{
struct nfattr *nest_helper;
const struct nf_conn_help *help = nfct_help(ct);
struct nf_conntrack_helper *helper;
if (!help || !help->helper)
if (!help)
return 0;
nest_helper = NFA_NEST(skb, CTA_HELP);
NFA_PUT(skb, CTA_HELP_NAME, strlen(help->helper->name), help->helper->name);
rcu_read_lock();
helper = rcu_dereference(help->helper);
if (!helper)
goto out;
if (help->helper->to_nfattr)
help->helper->to_nfattr(skb, ct);
nest_helper = NFA_NEST(skb, CTA_HELP);
NFA_PUT(skb, CTA_HELP_NAME, strlen(helper->name), helper->name);
if (helper->to_nfattr)
helper->to_nfattr(skb, ct);
NFA_NEST_END(skb, nest_helper);
out:
rcu_read_unlock();
return 0;
nfattr_failure:
rcu_read_unlock();
return -1;
}
@ -842,7 +850,7 @@ ctnetlink_change_helper(struct nf_conn *ct, struct nfattr *cda[])
if (help && help->helper) {
/* we had a helper before ... */
nf_ct_remove_expectations(ct);
help->helper = NULL;
rcu_assign_pointer(help->helper, NULL);
}
return 0;
@ -866,7 +874,7 @@ ctnetlink_change_helper(struct nf_conn *ct, struct nfattr *cda[])
/* need to zero data of old helper */
memset(&help->help, 0, sizeof(help->help));
help->helper = helper;
rcu_assign_pointer(help->helper, helper);
return 0;
}
@ -950,6 +958,7 @@ ctnetlink_create_conntrack(struct nfattr *cda[],
struct nf_conn *ct;
int err = -EINVAL;
struct nf_conn_help *help;
struct nf_conntrack_helper *helper = NULL;
ct = nf_conntrack_alloc(otuple, rtuple);
if (ct == NULL || IS_ERR(ct))
@ -980,14 +989,17 @@ ctnetlink_create_conntrack(struct nfattr *cda[],
#endif
help = nfct_help(ct);
if (help)
help->helper = nf_ct_helper_find_get(rtuple);
if (help) {
helper = nf_ct_helper_find_get(rtuple);
/* not in hash table yet so not strictly necessary */
rcu_assign_pointer(help->helper, helper);
}
add_timer(&ct->timeout);
nf_conntrack_hash_insert(ct);
if (help && help->helper)
nf_ct_helper_put(help->helper);
if (helper)
nf_ct_helper_put(helper);
return 0;

View File

@ -100,7 +100,6 @@ int nf_ct_gre_keymap_add(struct nf_conn *ct, enum ip_conntrack_dir dir,
struct nf_conn_help *help = nfct_help(ct);
struct nf_ct_gre_keymap **kmp, *km;
BUG_ON(strcmp(help->helper->name, "pptp"));
kmp = &help->help.ct_pptp_info.keymap[dir];
if (*kmp) {
/* check whether it's a retransmission */
@ -137,7 +136,6 @@ void nf_ct_gre_keymap_destroy(struct nf_conn *ct)
enum ip_conntrack_dir dir;
DEBUGP("entering for ct %p\n", ct);
BUG_ON(strcmp(help->helper->name, "pptp"));
write_lock_bh(&nf_ct_gre_lock);
for (dir = IP_CT_DIR_ORIGINAL; dir < IP_CT_DIR_MAX; dir++) {

View File

@ -59,7 +59,7 @@ static struct genl_family netlbl_cipsov4_gnl_family = {
};
/* NetLabel Netlink attribute policy */
static struct nla_policy netlbl_cipsov4_genl_policy[NLBL_CIPSOV4_A_MAX + 1] = {
static const struct nla_policy netlbl_cipsov4_genl_policy[NLBL_CIPSOV4_A_MAX + 1] = {
[NLBL_CIPSOV4_A_DOI] = { .type = NLA_U32 },
[NLBL_CIPSOV4_A_MTYPE] = { .type = NLA_U32 },
[NLBL_CIPSOV4_A_TAG] = { .type = NLA_U8 },

View File

@ -59,7 +59,7 @@ static struct genl_family netlbl_mgmt_gnl_family = {
};
/* NetLabel Netlink attribute policy */
static struct nla_policy netlbl_mgmt_genl_policy[NLBL_MGMT_A_MAX + 1] = {
static const struct nla_policy netlbl_mgmt_genl_policy[NLBL_MGMT_A_MAX + 1] = {
[NLBL_MGMT_A_DOMAIN] = { .type = NLA_NUL_STRING },
[NLBL_MGMT_A_PROTOCOL] = { .type = NLA_U32 },
[NLBL_MGMT_A_VERSION] = { .type = NLA_U32 },

View File

@ -61,7 +61,7 @@ static struct genl_family netlbl_unlabel_gnl_family = {
};
/* NetLabel Netlink attribute policy */
static struct nla_policy netlbl_unlabel_genl_policy[NLBL_UNLABEL_A_MAX + 1] = {
static const struct nla_policy netlbl_unlabel_genl_policy[NLBL_UNLABEL_A_MAX + 1] = {
[NLBL_UNLABEL_A_ACPTFLG] = { .type = NLA_U8 },
};

View File

@ -24,9 +24,9 @@ static u16 nla_attr_minlen[NLA_TYPE_MAX+1] __read_mostly = {
};
static int validate_nla(struct nlattr *nla, int maxtype,
struct nla_policy *policy)
const struct nla_policy *policy)
{
struct nla_policy *pt;
const struct nla_policy *pt;
int minlen = 0, attrlen = nla_len(nla);
if (nla->nla_type <= 0 || nla->nla_type > maxtype)
@ -99,7 +99,7 @@ static int validate_nla(struct nlattr *nla, int maxtype,
* Returns 0 on success or a negative error code.
*/
int nla_validate(struct nlattr *head, int len, int maxtype,
struct nla_policy *policy)
const struct nla_policy *policy)
{
struct nlattr *nla;
int rem, err;
@ -130,7 +130,7 @@ errout:
* Returns 0 on success or a negative error code.
*/
int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len,
struct nla_policy *policy)
const struct nla_policy *policy)
{
struct nlattr *nla;
int rem, err;

View File

@ -472,7 +472,7 @@ static struct sk_buff *ctrl_build_msg(struct genl_family *family, u32 pid,
return skb;
}
static struct nla_policy ctrl_policy[CTRL_ATTR_MAX+1] __read_mostly = {
static const struct nla_policy ctrl_policy[CTRL_ATTR_MAX+1] = {
[CTRL_ATTR_FAMILY_ID] = { .type = NLA_U16 },
[CTRL_ATTR_FAMILY_NAME] = { .type = NLA_NUL_STRING,
.len = GENL_NAMSIZ - 1 },

View File

@ -599,6 +599,7 @@ static void atm_tc_destroy(struct Qdisc *sch)
/* races ? */
while ((flow = p->flows)) {
tcf_destroy_chain(flow->filter_list);
flow->filter_list = NULL;
if (flow->ref > 1)
printk(KERN_ERR "atm_destroy: %p->ref = %d\n",flow,
flow->ref);

View File

@ -1748,10 +1748,12 @@ cbq_destroy(struct Qdisc* sch)
* classes from root to leafs which means that filters can still
* be bound to classes which have been destroyed already. --TGR '04
*/
for (h = 0; h < 16; h++)
for (cl = q->classes[h]; cl; cl = cl->next)
for (h = 0; h < 16; h++) {
for (cl = q->classes[h]; cl; cl = cl->next) {
tcf_destroy_chain(cl->filter_list);
cl->filter_list = NULL;
}
}
for (h = 0; h < 16; h++) {
struct cbq_class *next;

View File

@ -1744,20 +1744,23 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
int chunk;
struct sk_buff *skb;
unix_state_lock(sk);
skb = skb_dequeue(&sk->sk_receive_queue);
if (skb==NULL)
{
if (copied >= target)
break;
goto unlock;
/*
* POSIX 1003.1g mandates this order.
*/
if ((err = sock_error(sk)) != 0)
break;
goto unlock;
if (sk->sk_shutdown & RCV_SHUTDOWN)
break;
goto unlock;
unix_state_unlock(sk);
err = -EAGAIN;
if (!timeo)
break;
@ -1771,7 +1774,11 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
}
mutex_lock(&u->readlock);
continue;
unlock:
unix_state_unlock(sk);
break;
}
unix_state_unlock(sk);
if (check_creds) {
/* Never glue messages from different writers */

View File

@ -834,11 +834,67 @@ struct xfrm_policy *xfrm_policy_byid(u8 type, int dir, u32 id, int delete,
}
EXPORT_SYMBOL(xfrm_policy_byid);
void xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info)
#ifdef CONFIG_SECURITY_NETWORK_XFRM
static inline int
xfrm_policy_flush_secctx_check(u8 type, struct xfrm_audit *audit_info)
{
int dir;
int dir, err = 0;
for (dir = 0; dir < XFRM_POLICY_MAX; dir++) {
struct xfrm_policy *pol;
struct hlist_node *entry;
int i;
hlist_for_each_entry(pol, entry,
&xfrm_policy_inexact[dir], bydst) {
if (pol->type != type)
continue;
err = security_xfrm_policy_delete(pol);
if (err) {
xfrm_audit_log(audit_info->loginuid,
audit_info->secid,
AUDIT_MAC_IPSEC_DELSPD, 0,
pol, NULL);
return err;
}
}
for (i = xfrm_policy_bydst[dir].hmask; i >= 0; i--) {
hlist_for_each_entry(pol, entry,
xfrm_policy_bydst[dir].table + i,
bydst) {
if (pol->type != type)
continue;
err = security_xfrm_policy_delete(pol);
if (err) {
xfrm_audit_log(audit_info->loginuid,
audit_info->secid,
AUDIT_MAC_IPSEC_DELSPD,
0, pol, NULL);
return err;
}
}
}
}
return err;
}
#else
static inline int
xfrm_policy_flush_secctx_check(u8 type, struct xfrm_audit *audit_info)
{
return 0;
}
#endif
int xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info)
{
int dir, err = 0;
write_lock_bh(&xfrm_policy_lock);
err = xfrm_policy_flush_secctx_check(type, audit_info);
if (err)
goto out;
for (dir = 0; dir < XFRM_POLICY_MAX; dir++) {
struct xfrm_policy *pol;
struct hlist_node *entry;
@ -891,7 +947,9 @@ void xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info)
xfrm_policy_count[dir] -= killed;
}
atomic_inc(&flow_cache_genid);
out:
write_unlock_bh(&xfrm_policy_lock);
return err;
}
EXPORT_SYMBOL(xfrm_policy_flush);
@ -2583,4 +2641,3 @@ restore_state:
}
EXPORT_SYMBOL(xfrm_migrate);
#endif

View File

@ -391,12 +391,48 @@ int xfrm_state_delete(struct xfrm_state *x)
}
EXPORT_SYMBOL(xfrm_state_delete);
void xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info)
#ifdef CONFIG_SECURITY_NETWORK_XFRM
static inline int
xfrm_state_flush_secctx_check(u8 proto, struct xfrm_audit *audit_info)
{
int i;
int err = 0;
int i, err = 0;
for (i = 0; i <= xfrm_state_hmask; i++) {
struct hlist_node *entry;
struct xfrm_state *x;
hlist_for_each_entry(x, entry, xfrm_state_bydst+i, bydst) {
if (xfrm_id_proto_match(x->id.proto, proto) &&
(err = security_xfrm_state_delete(x)) != 0) {
xfrm_audit_log(audit_info->loginuid,
audit_info->secid,
AUDIT_MAC_IPSEC_DELSA,
0, NULL, x);
return err;
}
}
}
return err;
}
#else
static inline int
xfrm_state_flush_secctx_check(u8 proto, struct xfrm_audit *audit_info)
{
return 0;
}
#endif
int xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info)
{
int i, err = 0;
spin_lock_bh(&xfrm_state_lock);
err = xfrm_state_flush_secctx_check(proto, audit_info);
if (err)
goto out;
for (i = 0; i <= xfrm_state_hmask; i++) {
struct hlist_node *entry;
struct xfrm_state *x;
@ -419,8 +455,12 @@ restart:
}
}
}
err = 0;
out:
spin_unlock_bh(&xfrm_state_lock);
wake_up(&km_waitq);
return err;
}
EXPORT_SYMBOL(xfrm_state_flush);

View File

@ -1418,10 +1418,13 @@ static int xfrm_flush_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
struct km_event c;
struct xfrm_usersa_flush *p = NLMSG_DATA(nlh);
struct xfrm_audit audit_info;
int err;
audit_info.loginuid = NETLINK_CB(skb).loginuid;
audit_info.secid = NETLINK_CB(skb).sid;
xfrm_state_flush(p->proto, &audit_info);
err = xfrm_state_flush(p->proto, &audit_info);
if (err)
return err;
c.data.proto = p->proto;
c.event = nlh->nlmsg_type;
c.seq = nlh->nlmsg_seq;
@ -1582,7 +1585,9 @@ static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
audit_info.loginuid = NETLINK_CB(skb).loginuid;
audit_info.secid = NETLINK_CB(skb).sid;
xfrm_policy_flush(type, &audit_info);
err = xfrm_policy_flush(type, &audit_info);
if (err)
return err;
c.data.type = type;
c.event = nlh->nlmsg_type;
c.seq = nlh->nlmsg_seq;