ndisc.c (690e179059e7e89040d1cd564e39761567a8d5dc) ndisc.c (3e0b8f529c10037ae0b369fc892e524eae5a5485)
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Neighbour Discovery for IPv6
4 * Linux INET6 implementation
5 *
6 * Authors:
7 * Pedro Roque <roque@di.fc.ul.pt>
8 * Mike Shaver <shaver@ingenia.com>

--- 965 unchanged lines hidden (view full) ---

974 u8 *lladdr = NULL;
975 u32 ndoptlen = skb_tail_pointer(skb) - (skb_transport_header(skb) +
976 offsetof(struct nd_msg, opt));
977 struct ndisc_options ndopts;
978 struct net_device *dev = skb->dev;
979 struct inet6_dev *idev = __in6_dev_get(dev);
980 struct inet6_ifaddr *ifp;
981 struct neighbour *neigh;
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Neighbour Discovery for IPv6
4 * Linux INET6 implementation
5 *
6 * Authors:
7 * Pedro Roque <roque@di.fc.ul.pt>
8 * Mike Shaver <shaver@ingenia.com>

--- 965 unchanged lines hidden (view full) ---

974 u8 *lladdr = NULL;
975 u32 ndoptlen = skb_tail_pointer(skb) - (skb_transport_header(skb) +
976 offsetof(struct nd_msg, opt));
977 struct ndisc_options ndopts;
978 struct net_device *dev = skb->dev;
979 struct inet6_dev *idev = __in6_dev_get(dev);
980 struct inet6_ifaddr *ifp;
981 struct neighbour *neigh;
982 u8 new_state;
982
983 if (skb->len < sizeof(struct nd_msg)) {
984 ND_PRINTK(2, warn, "NA: packet too short\n");
985 return;
986 }
987
988 if (ipv6_addr_is_multicast(&msg->target)) {
989 ND_PRINTK(2, warn, "NA: target address is multicast\n");

--- 4 unchanged lines hidden (view full) ---

994 msg->icmph.icmp6_solicited) {
995 ND_PRINTK(2, warn, "NA: solicited NA is multicasted\n");
996 return;
997 }
998
999 /* For some 802.11 wireless deployments (and possibly other networks),
1000 * there will be a NA proxy and unsolicitd packets are attacks
1001 * and thus should not be accepted.
983
984 if (skb->len < sizeof(struct nd_msg)) {
985 ND_PRINTK(2, warn, "NA: packet too short\n");
986 return;
987 }
988
989 if (ipv6_addr_is_multicast(&msg->target)) {
990 ND_PRINTK(2, warn, "NA: target address is multicast\n");

--- 4 unchanged lines hidden (view full) ---

995 msg->icmph.icmp6_solicited) {
996 ND_PRINTK(2, warn, "NA: solicited NA is multicasted\n");
997 return;
998 }
999
1000 /* For some 802.11 wireless deployments (and possibly other networks),
1001 * there will be a NA proxy and unsolicitd packets are attacks
1002 * and thus should not be accepted.
1003 * drop_unsolicited_na takes precedence over accept_untracked_na
1002 */
1003 if (!msg->icmph.icmp6_solicited && idev &&
1004 idev->cnf.drop_unsolicited_na)
1005 return;
1006
1007 if (!ndisc_parse_options(dev, msg->opt, ndoptlen, &ndopts)) {
1008 ND_PRINTK(2, warn, "NS: invalid ND option\n");
1009 return;

--- 24 unchanged lines hidden (view full) ---

1034 */
1035 if (skb->pkt_type != PACKET_LOOPBACK)
1036 ND_PRINTK(1, warn,
1037 "NA: %pM advertised our address %pI6c on %s!\n",
1038 eth_hdr(skb)->h_source, &ifp->addr, ifp->idev->dev->name);
1039 in6_ifa_put(ifp);
1040 return;
1041 }
1004 */
1005 if (!msg->icmph.icmp6_solicited && idev &&
1006 idev->cnf.drop_unsolicited_na)
1007 return;
1008
1009 if (!ndisc_parse_options(dev, msg->opt, ndoptlen, &ndopts)) {
1010 ND_PRINTK(2, warn, "NS: invalid ND option\n");
1011 return;

--- 24 unchanged lines hidden (view full) ---

1036 */
1037 if (skb->pkt_type != PACKET_LOOPBACK)
1038 ND_PRINTK(1, warn,
1039 "NA: %pM advertised our address %pI6c on %s!\n",
1040 eth_hdr(skb)->h_source, &ifp->addr, ifp->idev->dev->name);
1041 in6_ifa_put(ifp);
1042 return;
1043 }
1044
1042 neigh = neigh_lookup(&nd_tbl, &msg->target, dev);
1043
1045 neigh = neigh_lookup(&nd_tbl, &msg->target, dev);
1046
1044 if (neigh) {
1047 /* RFC 9131 updates original Neighbour Discovery RFC 4861.
1048 * NAs with Target LL Address option without a corresponding
1049 * entry in the neighbour cache can now create a STALE neighbour
1050 * cache entry on routers.
1051 *
1052 * entry accept fwding solicited behaviour
1053 * ------- ------ ------ --------- ----------------------
1054 * present X X 0 Set state to STALE
1055 * present X X 1 Set state to REACHABLE
1056 * absent 0 X X Do nothing
1057 * absent 1 0 X Do nothing
1058 * absent 1 1 X Add a new STALE entry
1059 *
1060 * Note that we don't do a (daddr == all-routers-mcast) check.
1061 */
1062 new_state = msg->icmph.icmp6_solicited ? NUD_REACHABLE : NUD_STALE;
1063 if (!neigh && lladdr &&
1064 idev && idev->cnf.forwarding &&
1065 idev->cnf.accept_untracked_na) {
1066 neigh = neigh_create(&nd_tbl, &msg->target, dev);
1067 new_state = NUD_STALE;
1068 }
1069
1070 if (neigh && !IS_ERR(neigh)) {
1045 u8 old_flags = neigh->flags;
1046 struct net *net = dev_net(dev);
1047
1048 if (neigh->nud_state & NUD_FAILED)
1049 goto out;
1050
1051 /*
1052 * Don't update the neighbor cache entry on a proxy NA from
1053 * ourselves because either the proxied node is off link or it
1054 * has already sent a NA to us.
1055 */
1056 if (lladdr && !memcmp(lladdr, dev->dev_addr, dev->addr_len) &&
1057 net->ipv6.devconf_all->forwarding && net->ipv6.devconf_all->proxy_ndp &&
1058 pneigh_lookup(&nd_tbl, net, &msg->target, dev, 0)) {
1059 /* XXX: idev->cnf.proxy_ndp */
1060 goto out;
1061 }
1062
1063 ndisc_update(dev, neigh, lladdr,
1071 u8 old_flags = neigh->flags;
1072 struct net *net = dev_net(dev);
1073
1074 if (neigh->nud_state & NUD_FAILED)
1075 goto out;
1076
1077 /*
1078 * Don't update the neighbor cache entry on a proxy NA from
1079 * ourselves because either the proxied node is off link or it
1080 * has already sent a NA to us.
1081 */
1082 if (lladdr && !memcmp(lladdr, dev->dev_addr, dev->addr_len) &&
1083 net->ipv6.devconf_all->forwarding && net->ipv6.devconf_all->proxy_ndp &&
1084 pneigh_lookup(&nd_tbl, net, &msg->target, dev, 0)) {
1085 /* XXX: idev->cnf.proxy_ndp */
1086 goto out;
1087 }
1088
1089 ndisc_update(dev, neigh, lladdr,
1064 msg->icmph.icmp6_solicited ? NUD_REACHABLE : NUD_STALE,
1090 new_state,
1065 NEIGH_UPDATE_F_WEAK_OVERRIDE|
1066 (msg->icmph.icmp6_override ? NEIGH_UPDATE_F_OVERRIDE : 0)|
1067 NEIGH_UPDATE_F_OVERRIDE_ISROUTER|
1068 (msg->icmph.icmp6_router ? NEIGH_UPDATE_F_ISROUTER : 0),
1069 NDISC_NEIGHBOUR_ADVERTISEMENT, &ndopts);
1070
1071 if ((old_flags & ~neigh->flags) & NTF_ROUTER) {
1072 /*

--- 930 unchanged lines hidden ---
1091 NEIGH_UPDATE_F_WEAK_OVERRIDE|
1092 (msg->icmph.icmp6_override ? NEIGH_UPDATE_F_OVERRIDE : 0)|
1093 NEIGH_UPDATE_F_OVERRIDE_ISROUTER|
1094 (msg->icmph.icmp6_router ? NEIGH_UPDATE_F_ISROUTER : 0),
1095 NDISC_NEIGHBOUR_ADVERTISEMENT, &ndopts);
1096
1097 if ((old_flags & ~neigh->flags) & NTF_ROUTER) {
1098 /*

--- 930 unchanged lines hidden ---