From 85c1937b2693a0d4e39bb2644d720ed3703b9830 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 28 Jun 2005 12:39:40 -0700 Subject: [EBTABLES]: Fix thinkos in ebt_log.c When converting over the skb_header_pointer(), I converted parts of this module incorrectly. Kill the 'u' union in ebt_log() and all the bogus references to it. Signed-off-by: David S. Miller --- net/bridge/netfilter/ebt_log.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'net') diff --git a/net/bridge/netfilter/ebt_log.c b/net/bridge/netfilter/ebt_log.c index e4ae34b8892..662975be3d1 100644 --- a/net/bridge/netfilter/ebt_log.c +++ b/net/bridge/netfilter/ebt_log.c @@ -61,8 +61,6 @@ static void ebt_log(const struct sk_buff *skb, unsigned int hooknr, { struct ebt_log_info *info = (struct ebt_log_info *)data; char level_string[4] = "< >"; - union {struct iphdr iph; struct tcpudphdr ports; - struct arphdr arph; struct arppayload arpp;} u; level_string[1] = '0' + info->loglevel; spin_lock_bh(&ebt_log_lock); @@ -88,7 +86,7 @@ static void ebt_log(const struct sk_buff *skb, unsigned int hooknr, } printk(" IP SRC=%u.%u.%u.%u IP DST=%u.%u.%u.%u,", NIPQUAD(ih->saddr), NIPQUAD(ih->daddr)); - printk(" IP tos=0x%02X, IP proto=%d", u.iph.tos, + printk(" IP tos=0x%02X, IP proto=%d", ih->tos, ih->protocol); if (ih->protocol == IPPROTO_TCP || ih->protocol == IPPROTO_UDP) { @@ -127,7 +125,7 @@ static void ebt_log(const struct sk_buff *skb, unsigned int hooknr, ah->ar_pln == sizeof(uint32_t)) { struct arppayload _arpp, *ap; - ap = skb_header_pointer(skb, sizeof(u.arph), + ap = skb_header_pointer(skb, sizeof(_arph), sizeof(_arpp), &_arpp); if (ap == NULL) { printk(" INCOMPLETE ARP payload"); -- cgit v1.2.3-70-g09d2 From 4095ebf1e641b0f37ee1cd04c903bb85cf4ed25b Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Tue, 28 Jun 2005 12:49:30 -0700 Subject: [NETFILTER]: ipt_CLUSTERIP: fix ARP mangling This patch adds mangling of ARP requests (in addition to replies), since ARP caches are made from snooping both requests and replies. Signed-off-by: Harald Welte Signed-off-by: David S. Miller --- net/ipv4/netfilter/ipt_CLUSTERIP.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'net') diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c index 9cde8c61f52..6706d3a1bc4 100644 --- a/net/ipv4/netfilter/ipt_CLUSTERIP.c +++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c @@ -30,7 +30,7 @@ #include #include -#define CLUSTERIP_VERSION "0.6" +#define CLUSTERIP_VERSION "0.7" #define DEBUG_CLUSTERIP @@ -524,8 +524,9 @@ arp_mangle(unsigned int hook, || arp->ar_pln != 4 || arp->ar_hln != ETH_ALEN) return NF_ACCEPT; - /* we only want to mangle arp replies */ - if (arp->ar_op != htons(ARPOP_REPLY)) + /* we only want to mangle arp requests and replies */ + if (arp->ar_op != htons(ARPOP_REPLY) + && arp->ar_op != htons(ARPOP_REQUEST)) return NF_ACCEPT; payload = (void *)(arp+1); -- cgit v1.2.3-70-g09d2 From b3563c4fbff906991a1b4ef4609f99cca2a0de6a Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Tue, 28 Jun 2005 12:54:43 -0700 Subject: [NETLINK]: Clear padding in netlink messages Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- include/linux/netlink.h | 1 + include/linux/rtnetlink.h | 5 ++++- net/core/rtnetlink.c | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) (limited to 'net') diff --git a/include/linux/netlink.h b/include/linux/netlink.h index 3029cad63a0..27e4d164a10 100644 --- a/include/linux/netlink.h +++ b/include/linux/netlink.h @@ -168,6 +168,7 @@ __nlmsg_put(struct sk_buff *skb, u32 pid, u32 seq, int type, int len, int flags) nlh->nlmsg_flags = flags; nlh->nlmsg_pid = pid; nlh->nlmsg_seq = seq; + memset(NLMSG_DATA(nlh) + len, 0, NLMSG_ALIGN(size) - size); return nlh; } diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h index d021888b58f..dc26e82ba0f 100644 --- a/include/linux/rtnetlink.h +++ b/include/linux/rtnetlink.h @@ -898,7 +898,9 @@ extern void __rta_fill(struct sk_buff *skb, int attrtype, int attrlen, const voi memcpy(skb_put(skb, attrlen), data, attrlen); }) #define RTA_PUT_NOHDR(skb, attrlen, data) \ - RTA_APPEND(skb, RTA_ALIGN(attrlen), data) +({ RTA_APPEND(skb, RTA_ALIGN(attrlen), data); \ + memset(skb->tail - (RTA_ALIGN(attrlen) - attrlen), 0, \ + RTA_ALIGN(attrlen) - attrlen); }) #define RTA_PUT_U8(skb, attrtype, value) \ ({ u8 _tmp = (value); \ @@ -978,6 +980,7 @@ __rta_reserve(struct sk_buff *skb, int attrtype, int attrlen) rta = (struct rtattr*)skb_put(skb, RTA_ALIGN(size)); rta->rta_type = attrtype; rta->rta_len = size; + memset(RTA_DATA(rta) + attrlen, 0, RTA_ALIGN(size) - size); return rta; } diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index e013d836a7a..879237c378f 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -126,6 +126,7 @@ void __rta_fill(struct sk_buff *skb, int attrtype, int attrlen, const void *data rta->rta_type = attrtype; rta->rta_len = size; memcpy(RTA_DATA(rta), data, attrlen); + memset(RTA_DATA(rta) + attrlen, 0, RTA_ALIGN(size) - size); } size_t rtattr_strlcpy(char *dest, const struct rtattr *rta, size_t size) -- cgit v1.2.3-70-g09d2 From 9ef1d4c7c7aca1cd436612b6ca785b726ffb8ed8 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Tue, 28 Jun 2005 12:55:30 -0700 Subject: [NETLINK]: Missing initializations in dumped data Mostly missing initialization of padding fields of 1 or 2 bytes length, two instances of uninitialized nlmsgerr->msg of 16 bytes length. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/core/neighbour.c | 6 ++++++ net/core/rtnetlink.c | 1 + net/core/wireless.c | 1 + net/ipv4/ipmr.c | 10 ++++++++-- net/ipv6/addrconf.c | 1 + net/sched/act_api.c | 10 +++++++++- net/sched/cls_api.c | 2 ++ net/sched/sch_api.c | 2 ++ net/sched/sch_cbq.c | 2 ++ 9 files changed, 32 insertions(+), 3 deletions(-) (limited to 'net') diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 851eb927ed9..1beb782ac41 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -1598,6 +1598,8 @@ static int neightbl_fill_info(struct neigh_table *tbl, struct sk_buff *skb, read_lock_bh(&tbl->lock); ndtmsg->ndtm_family = tbl->family; + ndtmsg->ndtm_pad1 = 0; + ndtmsg->ndtm_pad2 = 0; RTA_PUT_STRING(skb, NDTA_NAME, tbl->id); RTA_PUT_MSECS(skb, NDTA_GC_INTERVAL, tbl->gc_interval); @@ -1683,6 +1685,8 @@ static int neightbl_fill_param_info(struct neigh_table *tbl, read_lock_bh(&tbl->lock); ndtmsg->ndtm_family = tbl->family; + ndtmsg->ndtm_pad1 = 0; + ndtmsg->ndtm_pad2 = 0; RTA_PUT_STRING(skb, NDTA_NAME, tbl->id); if (neightbl_fill_parms(skb, parms) < 0) @@ -1872,6 +1876,8 @@ static int neigh_fill_info(struct sk_buff *skb, struct neighbour *n, struct ndmsg *ndm = NLMSG_DATA(nlh); ndm->ndm_family = n->ops->family; + ndm->ndm_pad1 = 0; + ndm->ndm_pad2 = 0; ndm->ndm_flags = n->flags; ndm->ndm_type = n->type; ndm->ndm_ifindex = n->dev->ifindex; diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 879237c378f..4b1bb30e638 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -189,6 +189,7 @@ static int rtnetlink_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, nlh = NLMSG_NEW(skb, pid, seq, type, sizeof(*r), flags); r = NLMSG_DATA(nlh); r->ifi_family = AF_UNSPEC; + r->__ifi_pad = 0; r->ifi_type = dev->type; r->ifi_index = dev->ifindex; r->ifi_flags = dev_get_flags(dev); diff --git a/net/core/wireless.c b/net/core/wireless.c index b2fe378dfbf..3ff5639c0b7 100644 --- a/net/core/wireless.c +++ b/net/core/wireless.c @@ -1102,6 +1102,7 @@ static inline int rtnetlink_fill_iwinfo(struct sk_buff * skb, nlh = NLMSG_PUT(skb, 0, 0, type, sizeof(*r)); r = NLMSG_DATA(nlh); r->ifi_family = AF_UNSPEC; + r->__ifi_pad = 0; r->ifi_type = dev->type; r->ifi_index = dev->ifindex; r->ifi_flags = dev->flags; diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index e4f809a93f4..7833d920bdb 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -297,6 +297,7 @@ static int vif_delete(int vifi) static void ipmr_destroy_unres(struct mfc_cache *c) { struct sk_buff *skb; + struct nlmsgerr *e; atomic_dec(&cache_resolve_queue_len); @@ -306,7 +307,9 @@ static void ipmr_destroy_unres(struct mfc_cache *c) nlh->nlmsg_type = NLMSG_ERROR; nlh->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr)); skb_trim(skb, nlh->nlmsg_len); - ((struct nlmsgerr*)NLMSG_DATA(nlh))->error = -ETIMEDOUT; + e = NLMSG_DATA(nlh); + e->error = -ETIMEDOUT; + memset(&e->msg, 0, sizeof(e->msg)); netlink_unicast(rtnl, skb, NETLINK_CB(skb).dst_pid, MSG_DONTWAIT); } else kfree_skb(skb); @@ -499,6 +502,7 @@ static struct mfc_cache *ipmr_cache_alloc_unres(void) static void ipmr_cache_resolve(struct mfc_cache *uc, struct mfc_cache *c) { struct sk_buff *skb; + struct nlmsgerr *e; /* * Play the pending entries through our router @@ -515,7 +519,9 @@ static void ipmr_cache_resolve(struct mfc_cache *uc, struct mfc_cache *c) nlh->nlmsg_type = NLMSG_ERROR; nlh->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr)); skb_trim(skb, nlh->nlmsg_len); - ((struct nlmsgerr*)NLMSG_DATA(nlh))->error = -EMSGSIZE; + e = NLMSG_DATA(nlh); + e->error = -EMSGSIZE; + memset(&e->msg, 0, sizeof(e->msg)); } err = netlink_unicast(rtnl, skb, NETLINK_CB(skb).dst_pid, MSG_DONTWAIT); } else diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index a54d4ef3fd3..8140bed78a2 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -2923,6 +2923,7 @@ static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev, nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*r), flags); r = NLMSG_DATA(nlh); r->ifi_family = AF_INET6; + r->__ifi_pad = 0; r->ifi_type = dev->type; r->ifi_index = dev->ifindex; r->ifi_flags = dev_get_flags(dev); diff --git a/net/sched/act_api.c b/net/sched/act_api.c index 9594206e603..249c61936ea 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -439,6 +439,8 @@ tca_get_fill(struct sk_buff *skb, struct tc_action *a, u32 pid, u32 seq, t = NLMSG_DATA(nlh); t->tca_family = AF_UNSPEC; + t->tca__pad1 = 0; + t->tca__pad2 = 0; x = (struct rtattr*) skb->tail; RTA_PUT(skb, TCA_ACT_TAB, 0, NULL); @@ -580,6 +582,8 @@ static int tca_action_flush(struct rtattr *rta, struct nlmsghdr *n, u32 pid) nlh = NLMSG_PUT(skb, pid, n->nlmsg_seq, RTM_DELACTION, sizeof(*t)); t = NLMSG_DATA(nlh); t->tca_family = AF_UNSPEC; + t->tca__pad1 = 0; + t->tca__pad2 = 0; x = (struct rtattr *) skb->tail; RTA_PUT(skb, TCA_ACT_TAB, 0, NULL); @@ -687,7 +691,9 @@ static int tcf_add_notify(struct tc_action *a, u32 pid, u32 seq, int event, nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*t), flags); t = NLMSG_DATA(nlh); t->tca_family = AF_UNSPEC; - + t->tca__pad1 = 0; + t->tca__pad2 = 0; + x = (struct rtattr*) skb->tail; RTA_PUT(skb, TCA_ACT_TAB, 0, NULL); @@ -842,6 +848,8 @@ tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb) cb->nlh->nlmsg_type, sizeof(*t)); t = NLMSG_DATA(nlh); t->tca_family = AF_UNSPEC; + t->tca__pad1 = 0; + t->tca__pad2 = 0; x = (struct rtattr *) skb->tail; RTA_PUT(skb, TCA_ACT_TAB, 0, NULL); diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index 1616bf5c962..3b5714ef4d1 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c @@ -331,6 +331,8 @@ tcf_fill_node(struct sk_buff *skb, struct tcf_proto *tp, unsigned long fh, nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*tcm), flags); tcm = NLMSG_DATA(nlh); tcm->tcm_family = AF_UNSPEC; + tcm->tcm__pad1 = 0; + tcm->tcm__pad1 = 0; tcm->tcm_ifindex = tp->q->dev->ifindex; tcm->tcm_parent = tp->classid; tcm->tcm_info = TC_H_MAKE(tp->prio, tp->protocol); diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index 97c1c75d5c7..05e6e0a799d 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c @@ -770,6 +770,8 @@ static int tc_fill_qdisc(struct sk_buff *skb, struct Qdisc *q, u32 clid, nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*tcm), flags); tcm = NLMSG_DATA(nlh); tcm->tcm_family = AF_UNSPEC; + tcm->tcm__pad1 = 0; + tcm->tcm__pad2 = 0; tcm->tcm_ifindex = q->dev->ifindex; tcm->tcm_parent = clid; tcm->tcm_handle = q->handle; diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c index d43e3b8cbf6..baeb3111f75 100644 --- a/net/sched/sch_cbq.c +++ b/net/sched/sch_cbq.c @@ -1563,6 +1563,8 @@ static __inline__ int cbq_dump_police(struct sk_buff *skb, struct cbq_class *cl) if (cl->police) { opt.police = cl->police; + opt.__res1 = 0; + opt.__res2 = 0; RTA_PUT(skb, TCA_CBQ_POLICE, sizeof(opt), &opt); } return skb->len; -- cgit v1.2.3-70-g09d2 From 8a47077a0b5aa2649751c46e7a27884e6686ccbf Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Tue, 28 Jun 2005 12:56:45 -0700 Subject: [NETLINK]: Missing padding fields in dumped structures Plug holes with padding fields and initialized them to zero. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- include/linux/pkt_cls.h | 1 + include/linux/pkt_sched.h | 9 ++++++--- include/linux/rtnetlink.h | 5 +++++ net/ipv6/addrconf.c | 3 +++ net/sched/cls_rsvp.h | 1 + net/sched/sch_cbq.c | 1 + 6 files changed, 17 insertions(+), 3 deletions(-) (limited to 'net') diff --git a/include/linux/pkt_cls.h b/include/linux/pkt_cls.h index 25d2d67c1fa..bd2c5a2bbbf 100644 --- a/include/linux/pkt_cls.h +++ b/include/linux/pkt_cls.h @@ -276,6 +276,7 @@ struct tc_rsvp_pinfo __u8 protocol; __u8 tunnelid; __u8 tunnelhdr; + __u8 pad; }; /* ROUTE filter */ diff --git a/include/linux/pkt_sched.h b/include/linux/pkt_sched.h index 1d9da36eb9d..60ffcb9c579 100644 --- a/include/linux/pkt_sched.h +++ b/include/linux/pkt_sched.h @@ -221,9 +221,11 @@ struct tc_gred_qopt /* gred setup */ struct tc_gred_sopt { - __u32 DPs; - __u32 def_DP; - __u8 grio; + __u32 DPs; + __u32 def_DP; + __u8 grio; + __u8 pad1; + __u16 pad2; }; /* HTB section */ @@ -351,6 +353,7 @@ struct tc_cbq_ovl #define TC_CBQ_OVL_DROP 3 #define TC_CBQ_OVL_RCLASSIC 4 unsigned char priority2; + __u16 pad; __u32 penalty; }; diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h index dc26e82ba0f..657c05ab8f9 100644 --- a/include/linux/rtnetlink.h +++ b/include/linux/rtnetlink.h @@ -363,6 +363,8 @@ enum struct rta_session { __u8 proto; + __u8 pad1; + __u16 pad2; union { struct { @@ -635,10 +637,13 @@ struct ifinfomsg struct prefixmsg { unsigned char prefix_family; + unsigned char prefix_pad1; + unsigned short prefix_pad2; int prefix_ifindex; unsigned char prefix_type; unsigned char prefix_len; unsigned char prefix_flags; + unsigned char prefix_pad3; }; enum diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 8140bed78a2..1b2902d8eb9 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -3031,9 +3031,12 @@ static int inet6_fill_prefix(struct sk_buff *skb, struct inet6_dev *idev, nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*pmsg), flags); pmsg = NLMSG_DATA(nlh); pmsg->prefix_family = AF_INET6; + pmsg->prefix_pad1 = 0; + pmsg->prefix_pad2 = 0; pmsg->prefix_ifindex = idev->dev->ifindex; pmsg->prefix_len = pinfo->prefix_len; pmsg->prefix_type = pinfo->type; + pmsg->prefix_pad3 = 0; pmsg->prefix_flags = 0; if (pinfo->onlink) diff --git a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h index 232fb919681..006168d6937 100644 --- a/net/sched/cls_rsvp.h +++ b/net/sched/cls_rsvp.h @@ -618,6 +618,7 @@ static int rsvp_dump(struct tcf_proto *tp, unsigned long fh, pinfo.protocol = s->protocol; pinfo.tunnelid = s->tunnelid; pinfo.tunnelhdr = f->tunnelhdr; + pinfo.pad = 0; RTA_PUT(skb, TCA_RSVP_PINFO, sizeof(pinfo), &pinfo); if (f->res.classid) RTA_PUT(skb, TCA_RSVP_CLASSID, 4, &f->res.classid); diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c index baeb3111f75..09453f997d8 100644 --- a/net/sched/sch_cbq.c +++ b/net/sched/sch_cbq.c @@ -1528,6 +1528,7 @@ static __inline__ int cbq_dump_ovl(struct sk_buff *skb, struct cbq_class *cl) opt.strategy = cl->ovl_strategy; opt.priority2 = cl->priority2+1; + opt.pad = 0; opt.penalty = (cl->penalty*1000)/HZ; RTA_PUT(skb, TCA_CBQ_OVL_STRATEGY, sizeof(opt), &opt); return skb->len; -- cgit v1.2.3-70-g09d2 From ae9cda5d65f3d8a495241cbdcc2d56f721c83cc3 Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Tue, 28 Jun 2005 13:00:30 -0700 Subject: [IPV6]: Don't dump temporary addresses twice Each IPv6 Temporary Address (w/ CONFIG_IPV6_PRIVACY) is dumped twice to netlink. Because temporary addresses are listed in idev->addr_list, there's no need to dump idev->tempaddr separately. Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: David S. Miller --- net/ipv6/addrconf.c | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) (limited to 'net') diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 1b2902d8eb9..77004b9456c 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -2777,7 +2777,7 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb, read_lock_bh(&idev->lock); switch (type) { case UNICAST_ADDR: - /* unicast address */ + /* unicast address incl. temp addr */ for (ifa = idev->addr_list; ifa; ifa = ifa->if_next, ip_idx++) { if (ip_idx < s_ip_idx) @@ -2788,19 +2788,6 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb, NLM_F_MULTI)) <= 0) goto done; } - /* temp addr */ -#ifdef CONFIG_IPV6_PRIVACY - for (ifa = idev->tempaddr_list; ifa; - ifa = ifa->tmp_next, ip_idx++) { - if (ip_idx < s_ip_idx) - continue; - if ((err = inet6_fill_ifaddr(skb, ifa, - NETLINK_CB(cb->skb).pid, - cb->nlh->nlmsg_seq, RTM_NEWADDR, - NLM_F_MULTI)) <= 0) - goto done; - } -#endif break; case MULTICAST_ADDR: /* multicast address */ -- cgit v1.2.3-70-g09d2 From 2c2910a401f1ce2ac9136171e7522e731e1a2a8c Mon Sep 17 00:00:00 2001 From: Dietmar Eggemann Date: Tue, 28 Jun 2005 13:06:23 -0700 Subject: [IPV4]: Snmpv2 Mib IP counter ipInAddrErrors support I followed Thomas' proposal to see every martian destination as a case where the ipInAddrErrors counter has to be incremented. There are two advantages by doing so: (1) The relation between the ipInReceive counter and all the other ipInXXX counters is more accurate in the case the RTN_UNICAST code check fails and (2) it makes the code in ip_route_input_slow easier. Signed-off-by: Dietmar Eggemann Signed-off-by: David S. Miller --- net/ipv4/ip_input.c | 6 +++++- net/ipv4/route.c | 9 +++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) (limited to 'net') diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index af2ec88bbb2..c703528e0bc 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c @@ -283,14 +283,18 @@ static inline int ip_rcv_finish(struct sk_buff *skb) { struct net_device *dev = skb->dev; struct iphdr *iph = skb->nh.iph; + int err; /* * Initialise the virtual path cache for the packet. It describes * how the packet travels inside Linux networking. */ if (skb->dst == NULL) { - if (ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev)) + if ((err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev))) { + if (err == -EHOSTUNREACH) + IP_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS); goto drop; + } } #ifdef CONFIG_NET_CLS_ROUTE diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 80cf633d9f4..12a1cf306f6 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1909,7 +1909,7 @@ static int ip_route_input_slow(struct sk_buff *skb, u32 daddr, u32 saddr, */ if ((err = fib_lookup(&fl, &res)) != 0) { if (!IN_DEV_FORWARD(in_dev)) - goto e_inval; + goto e_hostunreach; goto no_route; } free_res = 1; @@ -1933,7 +1933,7 @@ static int ip_route_input_slow(struct sk_buff *skb, u32 daddr, u32 saddr, } if (!IN_DEV_FORWARD(in_dev)) - goto e_inval; + goto e_hostunreach; if (res.type != RTN_UNICAST) goto martian_destination; @@ -2025,6 +2025,11 @@ martian_destination: "%u.%u.%u.%u, dev %s\n", NIPQUAD(daddr), NIPQUAD(saddr), dev->name); #endif + +e_hostunreach: + err = -EHOSTUNREACH; + goto done; + e_inval: err = -EINVAL; goto done; -- cgit v1.2.3-70-g09d2 From 7a1af5d7bb94af16b980a53330436b9fadc12435 Mon Sep 17 00:00:00 2001 From: Maxime Bizon Date: Tue, 28 Jun 2005 13:21:12 -0700 Subject: [IPV4]: ipconfig.c: fix dhcp timeout behaviour I think there is a small bug in ipconfig.c in case IPCONFIG_DHCP is set and dhcp is used. When a DHCPOFFER is received, ip address is kept until we get DHCPACK. If no ack is received, ic_dynamic() returns negatively, but leaves the offered ip address in ic_myaddr. This makes the main loop in ip_auto_config() break and uses the maybe incomplete configuration. Not sure if it's the best way to do, but the following trivial patch correct this. Signed-off-by: Maxime Bizon Signed-off-by: David S. Miller --- net/ipv4/ipconfig.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'net') diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index f2509034ce7..d2bf8e1930a 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c @@ -1149,8 +1149,10 @@ static int __init ic_dynamic(void) ic_rarp_cleanup(); #endif - if (!ic_got_reply) + if (!ic_got_reply) { + ic_myaddr = INADDR_NONE; return -1; + } printk("IP-Config: Got %s answer from %u.%u.%u.%u, ", ((ic_got_reply & IC_RARP) ? "RARP" -- cgit v1.2.3-70-g09d2 From 2f85a42964dd43fed3a339701db046bee5a8b903 Mon Sep 17 00:00:00 2001 From: Vlad Yasevich Date: Tue, 28 Jun 2005 13:24:23 -0700 Subject: [SCTP] Make init & delayed sack timeouts configurable by user. Signed-off-by: Vlad Yasevich Signed-off-by: Sridhar Samudrala Signed-off-by: David S. Miller --- include/linux/sysctl.h | 1 + include/net/sctp/constants.h | 18 +++--------------- include/net/sctp/structs.h | 4 ++++ net/sctp/endpointola.c | 13 +++++-------- net/sctp/protocol.c | 5 ++++- net/sctp/sysctl.c | 13 +++++++++++++ net/sctp/transport.c | 1 - 7 files changed, 30 insertions(+), 25 deletions(-) (limited to 'net') diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index ebfe1250f0a..5b5f434ac9a 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -641,6 +641,7 @@ enum { NET_SCTP_ADDIP_ENABLE = 13, NET_SCTP_PRSCTP_ENABLE = 14, NET_SCTP_SNDBUF_POLICY = 15, + NET_SCTP_SACK_TIMEOUT = 16, }; /* /proc/sys/net/bridge */ diff --git a/include/net/sctp/constants.h b/include/net/sctp/constants.h index 4868c7f7749..5999e5684bb 100644 --- a/include/net/sctp/constants.h +++ b/include/net/sctp/constants.h @@ -263,23 +263,11 @@ enum { SCTP_MIN_PMTU = 576 }; enum { SCTP_MAX_DUP_TSNS = 16 }; enum { SCTP_MAX_GABS = 16 }; -/* Here we define the default timers. */ +/* Heartbeat interval - 30 secs */ +#define SCTP_DEFAULT_TIMEOUT_HEARTBEAT (30 * HZ) -/* cookie timer def = ? seconds */ -#define SCTP_DEFAULT_TIMEOUT_T1_COOKIE (3 * HZ) - -/* init timer def = 3 seconds */ -#define SCTP_DEFAULT_TIMEOUT_T1_INIT (3 * HZ) - -/* shutdown timer def = 300 ms */ -#define SCTP_DEFAULT_TIMEOUT_T2_SHUTDOWN ((300 * HZ) / 1000) - -/* 0 seconds + RTO */ -#define SCTP_DEFAULT_TIMEOUT_HEARTBEAT (10 * HZ) - -/* recv timer def = 200ms (in usec) */ +/* Delayed sack timer - 200ms */ #define SCTP_DEFAULT_TIMEOUT_SACK ((200 * HZ) / 1000) -#define SCTP_DEFAULT_TIMEOUT_SACK_MAX ((500 * HZ) / 1000) /* 500 ms */ /* RTO.Initial - 3 seconds * RTO.Min - 1 second diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index dfad4d3c581..47727c7cc62 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -161,6 +161,9 @@ extern struct sctp_globals { */ int sndbuf_policy; + /* Delayed SACK timeout 200ms default*/ + int sack_timeout; + /* HB.interval - 30 seconds */ int hb_interval; @@ -217,6 +220,7 @@ extern struct sctp_globals { #define sctp_sndbuf_policy (sctp_globals.sndbuf_policy) #define sctp_max_retrans_path (sctp_globals.max_retrans_path) #define sctp_max_retrans_init (sctp_globals.max_retrans_init) +#define sctp_sack_timeout (sctp_globals.sack_timeout) #define sctp_hb_interval (sctp_globals.hb_interval) #define sctp_max_instreams (sctp_globals.max_instreams) #define sctp_max_outstreams (sctp_globals.max_outstreams) diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c index 2ec0320fac3..c44bf4165c6 100644 --- a/net/sctp/endpointola.c +++ b/net/sctp/endpointola.c @@ -102,9 +102,9 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep, /* Set up the base timeout information. */ ep->timeouts[SCTP_EVENT_TIMEOUT_NONE] = 0; ep->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE] = - SCTP_DEFAULT_TIMEOUT_T1_COOKIE; + msecs_to_jiffies(sp->rtoinfo.srto_initial); ep->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT] = - SCTP_DEFAULT_TIMEOUT_T1_INIT; + msecs_to_jiffies(sp->rtoinfo.srto_initial); ep->timeouts[SCTP_EVENT_TIMEOUT_T2_SHUTDOWN] = msecs_to_jiffies(sp->rtoinfo.srto_initial); ep->timeouts[SCTP_EVENT_TIMEOUT_T3_RTX] = 0; @@ -117,12 +117,9 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep, ep->timeouts[SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD] = 5 * msecs_to_jiffies(sp->rtoinfo.srto_max); - ep->timeouts[SCTP_EVENT_TIMEOUT_HEARTBEAT] = - SCTP_DEFAULT_TIMEOUT_HEARTBEAT; - ep->timeouts[SCTP_EVENT_TIMEOUT_SACK] = - SCTP_DEFAULT_TIMEOUT_SACK; - ep->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] = - sp->autoclose * HZ; + ep->timeouts[SCTP_EVENT_TIMEOUT_HEARTBEAT] = 0; + ep->timeouts[SCTP_EVENT_TIMEOUT_SACK] = sctp_sack_timeout; + ep->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] = sp->autoclose * HZ; /* Use SCTP specific send buffer space queues. */ ep->sndbuf_policy = sctp_sndbuf_policy; diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 5135e1a25d2..e7f37faba7c 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -1050,7 +1050,10 @@ SCTP_STATIC __init int sctp_init(void) sctp_sndbuf_policy = 0; /* HB.interval - 30 seconds */ - sctp_hb_interval = 30 * HZ; + sctp_hb_interval = SCTP_DEFAULT_TIMEOUT_HEARTBEAT; + + /* delayed SACK timeout */ + sctp_sack_timeout = SCTP_DEFAULT_TIMEOUT_SACK; /* Implementation specific variables. */ diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c index 7fc31849312..dc4893474f1 100644 --- a/net/sctp/sysctl.c +++ b/net/sctp/sysctl.c @@ -47,6 +47,8 @@ static ctl_handler sctp_sysctl_jiffies_ms; static long rto_timer_min = 1; static long rto_timer_max = 86400000; /* One day */ +static long sack_timer_min = 1; +static long sack_timer_max = 500; static ctl_table sctp_table[] = { { @@ -187,6 +189,17 @@ static ctl_table sctp_table[] = { .mode = 0644, .proc_handler = &proc_dointvec }, + { + .ctl_name = NET_SCTP_SACK_TIMEOUT, + .procname = "sack_timeout", + .data = &sctp_sack_timeout, + .maxlen = sizeof(long), + .mode = 0644, + .proc_handler = &proc_doulongvec_ms_jiffies_minmax, + .strategy = &sctp_sysctl_jiffies_ms, + .extra1 = &sack_timer_min, + .extra2 = &sack_timer_max, + }, { .ctl_name = 0 } }; diff --git a/net/sctp/transport.c b/net/sctp/transport.c index 0ec0fde6e6c..a63b6917960 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c @@ -103,7 +103,6 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer, /* Set up the heartbeat timer. */ init_timer(&peer->hb_timer); - peer->hb_interval = SCTP_DEFAULT_TIMEOUT_HEARTBEAT; peer->hb_timer.function = sctp_generate_heartbeat_event; peer->hb_timer.data = (unsigned long)peer; -- cgit v1.2.3-70-g09d2 From f835e471b557c45d2e5701ea5215f6e739b4eb39 Mon Sep 17 00:00:00 2001 From: Robert Olsson Date: Tue, 28 Jun 2005 15:00:39 -0700 Subject: [IPV4]: Broken memory allocation in fib_trie This should help up the insertion... but the resize is more crucial. and complex and needs some thinking. Signed-off-by: Robert Olsson Signed-off-by: David S. Miller --- net/ipv4/fib_trie.c | 56 +++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 39 insertions(+), 17 deletions(-) (limited to 'net') diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 0671569ee6f..b56e88edf1b 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -43,7 +43,7 @@ * 2 of the License, or (at your option) any later version. */ -#define VERSION "0.323" +#define VERSION "0.324" #include #include @@ -341,8 +341,10 @@ static struct leaf *leaf_new(void) static struct leaf_info *leaf_info_new(int plen) { struct leaf_info *li = kmalloc(sizeof(struct leaf_info), GFP_KERNEL); - li->plen = plen; - INIT_LIST_HEAD(&li->falh); + if(li) { + li->plen = plen; + INIT_LIST_HEAD(&li->falh); + } return li; } @@ -879,8 +881,8 @@ static struct node *trie_rebalance(struct trie *t, struct tnode *tn) return (struct node*) tn; } -static struct list_head * -fib_insert_node(struct trie *t, u32 key, int plen) +static struct list_head * +fib_insert_node(struct trie *t, int *err, u32 key, int plen) { int pos, newpos; struct tnode *tp = NULL, *tn = NULL; @@ -940,7 +942,6 @@ fib_insert_node(struct trie *t, u32 key, int plen) if(tp && IS_LEAF(tp)) BUG(); - t->revision++; /* Case 1: n is a leaf. Compare prefixes */ @@ -949,8 +950,10 @@ fib_insert_node(struct trie *t, u32 key, int plen) li = leaf_info_new(plen); - if(! li) - BUG(); + if(! li) { + *err = -ENOMEM; + goto err; + } fa_head = &li->falh; insert_leaf_info(&l->list, li); @@ -959,14 +962,19 @@ fib_insert_node(struct trie *t, u32 key, int plen) t->size++; l = leaf_new(); - if(! l) - BUG(); + if(! l) { + *err = -ENOMEM; + goto err; + } l->key = key; li = leaf_info_new(plen); - if(! li) - BUG(); + if(! li) { + tnode_free((struct tnode *) l); + *err = -ENOMEM; + goto err; + } fa_head = &li->falh; insert_leaf_info(&l->list, li); @@ -1003,9 +1011,14 @@ fib_insert_node(struct trie *t, u32 key, int plen) newpos = 0; tn = tnode_new(key, newpos, 1); /* First tnode */ } - if(!tn) - trie_bug("tnode_pfx_new failed"); + if(!tn) { + free_leaf_info(li); + tnode_free((struct tnode *) l); + *err = -ENOMEM; + goto err; + } + NODE_SET_PARENT(tn, tp); missbit=tkey_extract_bits(key, newpos, 1); @@ -1027,7 +1040,9 @@ fib_insert_node(struct trie *t, u32 key, int plen) } /* Rebalance the trie */ t->trie = trie_rebalance(t, tp); -done:; +done: + t->revision++; +err:; return fa_head; } @@ -1156,8 +1171,12 @@ fn_trie_insert(struct fib_table *tb, struct rtmsg *r, struct kern_rta *rta, * Insert new entry to the list. */ - if(!fa_head) - fa_head = fib_insert_node(t, key, plen); + if(!fa_head) { + fa_head = fib_insert_node(t, &err, key, plen); + err = 0; + if(err) + goto out_free_new_fa; + } write_lock_bh(&fib_lock); @@ -1170,6 +1189,9 @@ fn_trie_insert(struct fib_table *tb, struct rtmsg *r, struct kern_rta *rta, rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen, tb->tb_id, nlhdr, req); succeeded: return 0; + +out_free_new_fa: + kmem_cache_free(fn_alias_kmem, new_fa); out: fib_release_info(fi); err:; -- cgit v1.2.3-70-g09d2 From fb3d89498d268c8dedc1ab5b15fa64f536564577 Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Tue, 28 Jun 2005 15:40:02 -0700 Subject: [IPVS]: Close race conditions on ip_vs_conn_tab list modification In an smp system, it is possible for an connection timer to expire, calling ip_vs_conn_expire while the connection table is being flushed, before ct_write_lock_bh is acquired. Since the list iterator loop in ip_vs_con_flush releases and re-acquires the spinlock (even though it doesn't re-enable softirqs), it is possible for the expiration function to modify the connection list, while it is being traversed in ip_vs_conn_flush. The result is that the next pointer gets set to NULL, and subsequently dereferenced, resulting in an oops. Signed-off-by: Neil Horman Acked-by: JulianAnastasov Signed-off-by: David S. Miller --- net/ipv4/ipvs/ip_vs_conn.c | 25 ++++--------------------- 1 file changed, 4 insertions(+), 21 deletions(-) (limited to 'net') diff --git a/net/ipv4/ipvs/ip_vs_conn.c b/net/ipv4/ipvs/ip_vs_conn.c index fd6feb5499f..9f16ab30910 100644 --- a/net/ipv4/ipvs/ip_vs_conn.c +++ b/net/ipv4/ipvs/ip_vs_conn.c @@ -548,7 +548,6 @@ void ip_vs_conn_expire_now(struct ip_vs_conn *cp) { if (del_timer(&cp->timer)) mod_timer(&cp->timer, jiffies); - __ip_vs_conn_put(cp); } @@ -764,7 +763,6 @@ void ip_vs_random_dropentry(void) { int idx; struct ip_vs_conn *cp; - struct ip_vs_conn *ct; /* * Randomly scan 1/32 of the whole table every second @@ -801,21 +799,12 @@ void ip_vs_random_dropentry(void) continue; } - /* - * Drop the entry, and drop its ct if not referenced - */ - atomic_inc(&cp->refcnt); - ct_write_unlock(hash); - - if ((ct = cp->control)) - atomic_inc(&ct->refcnt); IP_VS_DBG(4, "del connection\n"); ip_vs_conn_expire_now(cp); - if (ct) { + if (cp->control) { IP_VS_DBG(4, "del conn template\n"); - ip_vs_conn_expire_now(ct); + ip_vs_conn_expire_now(cp->control); } - ct_write_lock(hash); } ct_write_unlock(hash); } @@ -829,7 +818,6 @@ static void ip_vs_conn_flush(void) { int idx; struct ip_vs_conn *cp; - struct ip_vs_conn *ct; flush_again: for (idx=0; idxrefcnt); - ct_write_unlock(idx); - if ((ct = cp->control)) - atomic_inc(&ct->refcnt); IP_VS_DBG(4, "del connection\n"); ip_vs_conn_expire_now(cp); - if (ct) { + if (cp->control) { IP_VS_DBG(4, "del conn template\n"); - ip_vs_conn_expire_now(ct); + ip_vs_conn_expire_now(cp->control); } - ct_write_lock(idx); } ct_write_unlock_bh(idx); } -- cgit v1.2.3-70-g09d2 From 7fe40f73d7591b38f129fe6a9c0fa46e0b192d09 Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Tue, 28 Jun 2005 15:46:24 -0700 Subject: [IPV6]: remove more unused IPV6_AUTHHDR things. Remove two more unused IPV6_AUTHHDR option things, which I failed to remove them last time, plus, mark IPV6_AUTHHDR obsolete. Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: David S. Miller --- include/linux/in6.h | 2 +- include/net/ipv6.h | 1 - net/ipv6/ip6_flowlabel.c | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) (limited to 'net') diff --git a/include/linux/in6.h b/include/linux/in6.h index f8256c58284..dcf5720ffcb 100644 --- a/include/linux/in6.h +++ b/include/linux/in6.h @@ -156,7 +156,7 @@ struct in6_flowlabel_req #define IPV6_CHECKSUM 7 #define IPV6_HOPLIMIT 8 #define IPV6_NEXTHOP 9 -#define IPV6_AUTHHDR 10 +#define IPV6_AUTHHDR 10 /* obsolete */ #define IPV6_FLOWINFO 11 #define IPV6_UNICAST_HOPS 16 diff --git a/include/net/ipv6.h b/include/net/ipv6.h index 771b47e30f8..69324465e8b 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -183,7 +183,6 @@ struct ipv6_txoptions struct ipv6_opt_hdr *hopopt; struct ipv6_opt_hdr *dst0opt; struct ipv6_rt_hdr *srcrt; /* Routing Header */ - struct ipv6_opt_hdr *auth; struct ipv6_opt_hdr *dst1opt; /* Option buffer, as read by IPV6_PKTOPTIONS, starts here. */ diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c index 0e5f7499deb..b6c73da5ff3 100644 --- a/net/ipv6/ip6_flowlabel.c +++ b/net/ipv6/ip6_flowlabel.c @@ -244,7 +244,6 @@ struct ipv6_txoptions *fl6_merge_options(struct ipv6_txoptions * opt_space, opt_space->opt_nflen = 0; } opt_space->dst1opt = fopt->dst1opt; - opt_space->auth = fopt->auth; opt_space->opt_flen = fopt->opt_flen; return opt_space; } -- cgit v1.2.3-70-g09d2 From ff593c592a5d674822dce31143635b025f6415b2 Mon Sep 17 00:00:00 2001 From: Denis Vlasenko Date: Tue, 28 Jun 2005 15:49:06 -0700 Subject: [NET]: Micro optimization in eth_header() Signed-off-by: Denis Vlasenko Signed-off-by: David S. Miller --- net/ethernet/eth.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'net') diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c index 6617ea47d36..ab60ea63688 100644 --- a/net/ethernet/eth.c +++ b/net/ethernet/eth.c @@ -92,10 +92,9 @@ int eth_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, * Set the source hardware address. */ - if(saddr) - memcpy(eth->h_source,saddr,dev->addr_len); - else - memcpy(eth->h_source,dev->dev_addr,dev->addr_len); + if(!saddr) + saddr = dev->dev_addr; + memcpy(eth->h_source,saddr,dev->addr_len); /* * Anyway, the loopback-device should never use this function... -- cgit v1.2.3-70-g09d2 From 9666dae51013b064e7d77fc36b5cee98dd167ed5 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Tue, 28 Jun 2005 16:04:44 -0700 Subject: [NETFILTER]: Fix connection tracking bug in 2.6.12 In 2.6.12 we started dropping the conntrack reference when a packet leaves the IP layer. This broke connection tracking on a bridge, because bridge-netfilter defers calling some NF_IP_* hooks to the bridge layer for locally generated packets going out a bridge, where the conntrack reference is no longer available. This patch keeps the reference in this case as a temporary solution, long term we will remove the defered hook calling. No attempt is made to drop the reference in the bridge-code when it is no longer needed, tc actions could already have sent the packet anywhere. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/bridge/br_netfilter.c | 2 +- net/ipv4/ip_output.c | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'net') diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index 03ae4edddac..2d52fee63a8 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c @@ -844,7 +844,7 @@ static unsigned int ip_sabotage_out(unsigned int hook, struct sk_buff **pskb, * doesn't use the bridge parent of the indev by using * the BRNF_DONT_TAKE_PARENT mask. */ if (hook == NF_IP_FORWARD && nf_bridge->physindev == NULL) { - nf_bridge->mask &= BRNF_DONT_TAKE_PARENT; + nf_bridge->mask |= BRNF_DONT_TAKE_PARENT; nf_bridge->physindev = (struct net_device *)in; } #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index ee07aec215a..6ce5c3292f9 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -188,7 +188,13 @@ static inline int ip_finish_output2(struct sk_buff *skb) skb = skb2; } - nf_reset(skb); +#ifdef CONFIG_BRIDGE_NETFILTER + /* bridge-netfilter defers calling some IP hooks to the bridge layer + * and still needs the conntrack reference. + */ + if (skb->nf_bridge == NULL) +#endif + nf_reset(skb); if (hh) { int hh_alen; -- cgit v1.2.3-70-g09d2