lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Thu, 12 Mar 2015 19:05:48 +0900 From: YOSHIFUJI Hideaki/吉藤英明 <hideaki.yoshifuji@...aclelinux.com> To: Zhu Yanjun <Yanjun.Zhu@...driver.com>, brian.haley@...com, davem@...emloft.net, alexandre.dietsch@...driver.com, clinton.slabbert@...driver.com, kuznet@....inr.ac.ru, jmorris@...ei.org, kaber@...sh.net, netdev@...r.kernel.org, ulf.samuelsson@...csson.com CC: hideaki.yoshifuji@...aclelinux.com Subject: Re: [PATCH V2 1/1] neighbour: Support broadcast ARP in neighbor PROPE state Hi, Zhu Yanjun wrote: > From: Zhu Yanjun <yanjun.zhu@...driver.com> > > When the neighbor state machine is in PROBE state, it will normally send > a number of unicast ARP requests (number defined in "ucast_probes" entry > in the proc file system, default=3) and if no reply is received, it will > change state to FAILED. > > Enabling CONFIG_ARP_PROBE_BCAST, will make the state machine try to send > broadcast ARP requests if the unicast ARP requests failed. The state machine > will only enter FAILED state if the broadcast ARP requests did not receive > a reply. > > Enabling CONFIG_ARP_PROBE_BCAST, makes the IPv4 ARP behaviour more > similar to the IPv6 Neighbor Discovery protocol, and is necessary, > if the other end only responds to broadcast ARPs. I don't think There are any difference between the state machine of ARP and the state machine of NDP here. --yoshfuji > > CC: WANG Cong <xiyou.wangcong@...il.com> > Reviewed-by: Yang Shi <yang.shi@...driver.com> > Signed-off-by: eulfsam <ulf.samuelsson@...driver.com> > Signed-off-by: Zhu Yanjun <yanjun.zhu@...driver.com> > --- > include/net/neighbour.h | 7 ++++++ > include/uapi/linux/neighbour.h | 6 +++++ > include/uapi/linux/sysctl.h | 3 +++ > kernel/sysctl_binary.c | 3 +++ > net/core/neighbour.c | 44 +++++++++++++++++++++++++++++--- > net/ipv4/Kconfig | 57 ++++++++++++++++++++++++++++++++++++++++++ > net/ipv4/arp.c | 7 ++++-- > 7 files changed, 121 insertions(+), 6 deletions(-) > > diff --git a/include/net/neighbour.h b/include/net/neighbour.h > index 76f7084..85070b2 100644 > --- a/include/net/neighbour.h > +++ b/include/net/neighbour.h > @@ -40,6 +40,9 @@ struct neighbour; > > enum { > NEIGH_VAR_MCAST_PROBES, > +#ifdef CONFIG_IP_ARP_BROADCAST > + NEIGH_VAR_BCAST_PROBES, > +#endif > NEIGH_VAR_UCAST_PROBES, > NEIGH_VAR_APP_PROBES, > NEIGH_VAR_RETRANS_TIME, > @@ -122,6 +125,10 @@ struct neigh_statistics { > unsigned long rcv_probes_mcast; /* number of received mcast ipv6 */ > unsigned long rcv_probes_ucast; /* number of received ucast ipv6 */ > > +#ifdef CONFIG_IP_ARP_BROADCAST > + unsigned long rcv_probes_bcast; /* number of received ucast ipv6 */ > +#endif > + > unsigned long periodic_gc_runs; /* number of periodic GC runs */ > unsigned long forced_gc_runs; /* number of forced GC runs */ > > diff --git a/include/uapi/linux/neighbour.h b/include/uapi/linux/neighbour.h > index 3873a35..79cef9e 100644 > --- a/include/uapi/linux/neighbour.h > +++ b/include/uapi/linux/neighbour.h > @@ -103,6 +103,9 @@ struct ndt_stats { > __u64 ndts_lookups; > __u64 ndts_hits; > __u64 ndts_rcv_probes_mcast; > +#ifdef CONFIG_IP_ARP_BROADCAST > + __u64 ndts_rcv_probes_bcast; > +#endif > __u64 ndts_rcv_probes_ucast; > __u64 ndts_periodic_gc_runs; > __u64 ndts_forced_gc_runs; > @@ -121,6 +124,9 @@ enum { > NDTPA_APP_PROBES, /* u32 */ > NDTPA_UCAST_PROBES, /* u32 */ > NDTPA_MCAST_PROBES, /* u32 */ > +#ifdef CONFIG_IP_ARP_BROADCAST > + NDTPA_BCAST_PROBES, /* u32 */ > +#endif > NDTPA_ANYCAST_DELAY, /* u64, msecs */ > NDTPA_PROXY_DELAY, /* u64, msecs */ > NDTPA_PROXY_QLEN, /* u32 */ > diff --git a/include/uapi/linux/sysctl.h b/include/uapi/linux/sysctl.h > index 0956373..0c54d16 100644 > --- a/include/uapi/linux/sysctl.h > +++ b/include/uapi/linux/sysctl.h > @@ -598,6 +598,9 @@ enum { > NET_NEIGH_GC_THRESH3=16, > NET_NEIGH_RETRANS_TIME_MS=17, > NET_NEIGH_REACHABLE_TIME_MS=18, > +#ifdef CONFIG_IP_ARP_BROADCAST > + NET_NEIGH_BCAST_SOLICIT=19, > +#endif > }; > > /* /proc/sys/net/dccp */ > diff --git a/kernel/sysctl_binary.c b/kernel/sysctl_binary.c > index 7e7746a..47482a6 100644 > --- a/kernel/sysctl_binary.c > +++ b/kernel/sysctl_binary.c > @@ -267,6 +267,9 @@ static const struct bin_table bin_net_neigh_vars_table[] = { > { CTL_INT, NET_NEIGH_MCAST_SOLICIT, "mcast_solicit" }, > { CTL_INT, NET_NEIGH_UCAST_SOLICIT, "ucast_solicit" }, > { CTL_INT, NET_NEIGH_APP_SOLICIT, "app_solicit" }, > +#ifdef CONFIG_IP_ARP_BROADCAST > + { CTL_INT, NET_NEIGH_BCAST_SOLICIT, "bcast_solicit" }, > +#endif > /* NET_NEIGH_RETRANS_TIME "retrans_time" no longer used */ > { CTL_INT, NET_NEIGH_REACHABLE_TIME, "base_reachable_time" }, > { CTL_INT, NET_NEIGH_DELAY_PROBE_TIME, "delay_first_probe_time" }, > diff --git a/net/core/neighbour.c b/net/core/neighbour.c > index 70fe9e1..b372af4 100644 > --- a/net/core/neighbour.c > +++ b/net/core/neighbour.c > @@ -936,10 +936,16 @@ static void neigh_timer_handler(unsigned long arg) > > if ((neigh->nud_state & (NUD_INCOMPLETE | NUD_PROBE)) && > atomic_read(&neigh->probes) >= neigh_max_probes(neigh)) { > - neigh->nud_state = NUD_FAILED; > - notify = 1; > - neigh_invalidate(neigh); > - goto out; > +#ifdef CONFIG_IP_ARP_BROADCAST > + int delta_probes = atomic_read(&neigh->probes) - neigh_max_probes(neigh); > + if (delta_probes >= NEIGH_VAR(neigh->parms, BCAST_PROBES)) > +#endif > + { > + neigh->nud_state = NUD_FAILED; > + notify = 1; > + neigh_invalidate(neigh); > + goto out; > + } > } > > if (neigh->nud_state & NUD_IN_TIMER) { > @@ -973,6 +979,7 @@ int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb) > goto out_unlock_bh; > > if (!(neigh->nud_state & (NUD_STALE | NUD_INCOMPLETE))) { > + /* We are in (NUD_NONE | NUD_FAILED) */ > if (NEIGH_VAR(neigh->parms, MCAST_PROBES) + > NEIGH_VAR(neigh->parms, APP_PROBES)) { > unsigned long next, now = jiffies; > @@ -1783,6 +1790,10 @@ static int neightbl_fill_parms(struct sk_buff *skb, struct neigh_parms *parms) > NEIGH_VAR(parms, UCAST_PROBES)) || > nla_put_u32(skb, NDTPA_MCAST_PROBES, > NEIGH_VAR(parms, MCAST_PROBES)) || > +#ifdef CONFIG_IP_ARP_BROADCAST > + nla_put_u32(skb, NDTPA_BCAST_PROBES, > + NEIGH_VAR(parms, BCAST_PROBES)) || > +#endif > nla_put_msecs(skb, NDTPA_REACHABLE_TIME, parms->reachable_time) || > nla_put_msecs(skb, NDTPA_BASE_REACHABLE_TIME, > NEIGH_VAR(parms, BASE_REACHABLE_TIME)) || > @@ -1870,6 +1881,9 @@ static int neightbl_fill_info(struct sk_buff *skb, struct neigh_table *tbl, > ndst.ndts_lookups += st->lookups; > ndst.ndts_hits += st->hits; > ndst.ndts_rcv_probes_mcast += st->rcv_probes_mcast; > +#ifdef CONFIG_IP_ARP_BROADCAST > + ndst.ndts_rcv_probes_bcast += st->rcv_probes_bcast; > +#endif > ndst.ndts_rcv_probes_ucast += st->rcv_probes_ucast; > ndst.ndts_periodic_gc_runs += st->periodic_gc_runs; > ndst.ndts_forced_gc_runs += st->forced_gc_runs; > @@ -1942,6 +1956,9 @@ static const struct nla_policy nl_ntbl_parm_policy[NDTPA_MAX+1] = { > [NDTPA_APP_PROBES] = { .type = NLA_U32 }, > [NDTPA_UCAST_PROBES] = { .type = NLA_U32 }, > [NDTPA_MCAST_PROBES] = { .type = NLA_U32 }, > +#ifdef CONFIG_IP_ARP_BROADCAST > + [NDTPA_BCAST_PROBES] = { .type = NLA_U32 }, > +#endif > [NDTPA_BASE_REACHABLE_TIME] = { .type = NLA_U64 }, > [NDTPA_GC_STALETIME] = { .type = NLA_U64 }, > [NDTPA_DELAY_PROBE_TIME] = { .type = NLA_U64 }, > @@ -2042,6 +2059,12 @@ static int neightbl_set(struct sk_buff *skb, struct nlmsghdr *nlh) > NEIGH_VAR_SET(p, MCAST_PROBES, > nla_get_u32(tbp[i])); > break; > +#ifdef CONFIG_IP_ARP_BROADCAST > + case NDTPA_BCAST_PROBES: > + NEIGH_VAR_SET(p, BCAST_PROBES, > + nla_get_u32(tbp[i])); > + break; > +#endif > case NDTPA_BASE_REACHABLE_TIME: > NEIGH_VAR_SET(p, BASE_REACHABLE_TIME, > nla_get_msecs(tbp[i])); > @@ -2702,11 +2725,18 @@ static int neigh_stat_seq_show(struct seq_file *seq, void *v) > struct neigh_statistics *st = v; > > if (v == SEQ_START_TOKEN) { > +#ifdef CONFIG_IP_ARP_BROADCAST > + seq_printf(seq, "entries allocs destroys hash_grows lookups hits res_failed rcv_probes_bcast rcv_probes_mcast rcv_probes_ucast periodic_gc_runs forced_gc_runs unresolved_discards\n"); > +#else > seq_printf(seq, "entries allocs destroys hash_grows lookups hits res_failed rcv_probes_mcast rcv_probes_ucast periodic_gc_runs forced_gc_runs unresolved_discards\n"); > +#endif > return 0; > } > > seq_printf(seq, "%08x %08lx %08lx %08lx %08lx %08lx %08lx " > +#ifdef CONFIG_IP_ARP_BROADCAST > + "%08lx " > +#endif > "%08lx %08lx %08lx %08lx %08lx\n", > atomic_read(&tbl->entries), > > @@ -2719,6 +2749,9 @@ static int neigh_stat_seq_show(struct seq_file *seq, void *v) > > st->res_failed, > > +#ifdef CONFIG_IP_ARP_BROADCAST > + st->rcv_probes_bcast, > +#endif > st->rcv_probes_mcast, > st->rcv_probes_ucast, > > @@ -2992,6 +3025,9 @@ static struct neigh_sysctl_table { > } neigh_sysctl_template __read_mostly = { > .neigh_vars = { > NEIGH_SYSCTL_ZERO_INTMAX_ENTRY(MCAST_PROBES, "mcast_solicit"), > +#ifdef CONFIG_IP_ARP_BROADCAST > + NEIGH_SYSCTL_ZERO_INTMAX_ENTRY(BCAST_PROBES, "bcast_solicit"), > +#endif > NEIGH_SYSCTL_ZERO_INTMAX_ENTRY(UCAST_PROBES, "ucast_solicit"), > NEIGH_SYSCTL_ZERO_INTMAX_ENTRY(APP_PROBES, "app_solicit"), > NEIGH_SYSCTL_USERHZ_JIFFIES_ENTRY(RETRANS_TIME, "retrans_time"), > diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig > index bd29016..2f43dc9 100644 > --- a/net/ipv4/Kconfig > +++ b/net/ipv4/Kconfig > @@ -1,6 +1,63 @@ > # > # IP configuration > # > +config IP_ARP_BROADCAST > + bool "IP: allow broadcast ARP" > + default N > + ---help--- > + The stack will periodically refresh ARP cache by sending unicast ARP requests. > + if a number of unicast ARP request fails, the stack will normally enter > + FAILED state, and the ARP entry will be removed by the garbage collector. > + Enabling this option will make the stack try to send broadcast ARP requests > + if the unicast ARP requests fails, before entering FAILED state. > + The number of broadcast packets is controlled by > + '/proc/sys/net/ipv4/neigh/<dev>/bcast_solicit' which defaults to "0". > + The parameter must be assigned a value to enable sending broadcast ARPs. > + > + If unsure, say N here. > + > + > +config IP_ARP_UCAST_PROBES > + int "ucast_solicit initial value" > + default "3" > + > + ---help--- > + This value defines the initial value for how many unicast ARP requests > + are sent by the ARP state machine in PROBE state. > + It can be controlled runtime by '/proc/sys/net/ipv4/neigh/<dev>/ucast_solicit' > + > + If unsure, say "3" here. > + > + > +config IP_ARP_MCAST_PROBES > + int "mcast_solicit initial value" > + default "3" > + > + ---help--- > + This value defines the initial value for how many broadcast ARP requests > + are sent by the ARP state machine in INCOMPLETE state. > + It can be controlled runtime by '/proc/sys/net/ipv4/neigh/<dev>/mcast_solicit' > + > + If unsure, say "3" here. > + > + > +config IP_ARP_BCAST_PROBES > + int "bcast_solicit initial value" > + depends on IP_ARP_BROADCAST > + default "0" > + > + ---help--- > + This value defines the initial value for how many broadcast ARP requests > + are sent by the ARP state machine in PROBE state. > + It can be controlled runtime by '/proc/sys/net/ipv4/neigh/<dev>/bcast_solicit' > + The default value of 'bcast_solicit' is zero, mimicking the behaviour of > + older kernels which does not send out broadcast ARPs except for new entries. > + If you want broadcast ARP requests to happen in PROBE state, set the number here. > + To be compatible with IPv6, the number should be "3" > + > + If unsure, say "0" here. > + > + > config IP_MULTICAST > bool "IP: multicasting" > help > diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c > index 205e147..4795ab6 100644 > --- a/net/ipv4/arp.c > +++ b/net/ipv4/arp.c > @@ -168,8 +168,11 @@ struct neigh_table arp_tbl = { > .tbl = &arp_tbl, > .reachable_time = 30 * HZ, > .data = { > - [NEIGH_VAR_MCAST_PROBES] = 3, > - [NEIGH_VAR_UCAST_PROBES] = 3, > + [NEIGH_VAR_MCAST_PROBES] = CONFIG_IP_ARP_MCAST_PROBES, > + [NEIGH_VAR_UCAST_PROBES] = CONFIG_IP_ARP_UCAST_PROBES, > +#ifdef CONFIG_IP_ARP_BROADCAST > + [NEIGH_VAR_BCAST_PROBES] = CONFIG_IP_ARP_BCAST_PROBES, > +#endif > [NEIGH_VAR_RETRANS_TIME] = 1 * HZ, > [NEIGH_VAR_BASE_REACHABLE_TIME] = 30 * HZ, > [NEIGH_VAR_DELAY_PROBE_TIME] = 5 * HZ, > -- 吉藤英明 <hideaki.yoshifuji@...aclelinux.com> ミラクル・リナックス株式会社 技術本部 サポート部 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@...r.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists