--- zzzz-none-000/linux-5.15.111/net/ipv6/addrconf.c 2023-05-11 14:00:40.000000000 +0000 +++ puma7-arm-6670-761/linux-5.15.111/net/ipv6/addrconf.c 2024-02-07 09:28:09.000000000 +0000 @@ -33,6 +33,10 @@ * selection; consider scope, * status etc. */ + /* + Includes Intel Corporation's changes/modifications dated: [2/3/2014]. + Changed/modified portions - Copyright © [2014], Intel Corporation. + */ #define pr_fmt(fmt) "IPv6: " fmt @@ -171,6 +175,11 @@ const struct net_device *dev, u32 flags, u32 noflags, bool no_gw); +static struct fib6_info *addrconf_get_prefix_route_by_table(const struct in6_addr *pfx, + int plen, + const struct net_device *dev, + u32 flags, u32 noflags, + bool no_gw, u32 table_id); static void addrconf_dad_start(struct inet6_ifaddr *ifp); static void addrconf_dad_work(struct work_struct *w); @@ -189,6 +198,7 @@ .hop_limit = IPV6_DEFAULT_HOPLIMIT, .mtu6 = IPV6_MIN_MTU, .accept_ra = 1, + .accept_ra_table = RT6_TABLE_DFLT, .accept_redirects = 1, .autoconf = 1, .force_mld_version = 0, @@ -210,6 +220,7 @@ .accept_ra_from_local = 0, .accept_ra_min_hop_limit= 1, .accept_ra_pinfo = 1, + .accept_ra_pinfo_autoconf = 1, #ifdef CONFIG_IPV6_ROUTER_PREF .accept_ra_rtr_pref = 1, .rtr_probe_interval = 60 * HZ, @@ -248,6 +259,7 @@ .hop_limit = IPV6_DEFAULT_HOPLIMIT, .mtu6 = IPV6_MIN_MTU, .accept_ra = 1, + .accept_ra_table = RT6_TABLE_DFLT, .accept_redirects = 1, .autoconf = 1, .force_mld_version = 0, @@ -269,6 +281,7 @@ .accept_ra_from_local = 0, .accept_ra_min_hop_limit= 1, .accept_ra_pinfo = 1, + .accept_ra_pinfo_autoconf = 1, #ifdef CONFIG_IPV6_ROUTER_PREF .accept_ra_rtr_pref = 1, .rtr_probe_interval = 60 * HZ, @@ -1880,6 +1893,45 @@ return err; } +/*! \fn int intel_ipv6_ns_filter(struct net_device *dev, const struct in6_addr* dst_addr, unsigned char banned_flags) + * \brief filter neighbour solicit packets not destined to the device + * \param[in] - dev - the device the packet was received in + * \param[in] - dst_addr - the destination address of the packet + * \param[in] - banned_flags - ipv6 address banned flags. the banned flags are the ipv6 adress flags that we want to ignore + * the flags could be + * IFA_F_TEMPORARY,IFA_F_SECONDARY,IFA_F_NODAD, IFA_F_OPTIMISTIC,IFA_F_DADFAILED,IFA_F_HOMEADDRESS,IFA_F_DEPRECATED,IFA_F_TENTATIVE + * so if we want to ignore addresses that are temporary ipv6 addresses we'll add IFA_F_TEMPORARY to banned_flags + * \return 1/0 - 1 = accept, 0 = drop + */ +int intel_ipv6_ns_filter(struct net_device *dev, const struct in6_addr* dst_addr, unsigned char banned_flags) +{ + struct inet6_dev *idev; + int accept = 0; + + idev = __in6_dev_get(dev); + if (idev) + { + struct inet6_ifaddr *ifp; + read_lock_bh(&idev->lock); + list_for_each_entry(ifp, &idev->addr_list, if_list) + { + if (!(ifp->flags & banned_flags)) + { + /* compare the last 3 bytes of the destination address to the last 3 bytes of the device's ipv6 address*/ + if ((ifp->addr.in6_u.u6_addr8[15] == dst_addr->in6_u.u6_addr8[15]) && + (ifp->addr.in6_u.u6_addr8[14] == dst_addr->in6_u.u6_addr8[14]) && + (ifp->addr.in6_u.u6_addr8[13] == dst_addr->in6_u.u6_addr8[13])) + { + accept =1; + break; + } + } + } + read_unlock_bh(&idev->lock); + } + return accept; +} + static int ipv6_count_addresses(const struct inet6_dev *idev) { const struct inet6_ifaddr *ifp; @@ -2399,12 +2451,12 @@ */ static void -addrconf_prefix_route(struct in6_addr *pfx, int plen, u32 metric, +addrconf_prefix_route_by_table(struct in6_addr *pfx, int plen, u32 metric, struct net_device *dev, unsigned long expires, - u32 flags, gfp_t gfp_flags) + u32 flags, gfp_t gfp_flags, u32 table_id) { struct fib6_config cfg = { - .fc_table = l3mdev_fib_table(dev) ? : RT6_TABLE_PREFIX, + .fc_table = table_id, .fc_metric = metric ? : IP6_RT_PRIO_ADDRCONF, .fc_ifindex = dev->ifindex, .fc_expires = expires, @@ -2428,20 +2480,26 @@ ip6_route_add(&cfg, gfp_flags, NULL); } +static void +addrconf_prefix_route(struct in6_addr *pfx, int plen, u32 metric, + struct net_device *dev, unsigned long expires, + u32 flags, gfp_t gfp_flags) +{ + addrconf_prefix_route_by_table(pfx, plen, metric, dev, expires, flags, gfp_flags, RT6_TABLE_PREFIX); +} -static struct fib6_info *addrconf_get_prefix_route(const struct in6_addr *pfx, +static struct fib6_info *addrconf_get_prefix_route_by_table(const struct in6_addr *pfx, int plen, const struct net_device *dev, u32 flags, u32 noflags, - bool no_gw) + bool no_gw, u32 table_id) { struct fib6_node *fn; struct fib6_info *rt = NULL; struct fib6_table *table; - u32 tb_id = l3mdev_fib_table(dev) ? : RT6_TABLE_PREFIX; - table = fib6_get_table(dev_net(dev), tb_id); + table = fib6_get_table(dev_net(dev), table_id); if (!table) return NULL; @@ -2472,6 +2530,14 @@ return rt; } +static struct fib6_info *addrconf_get_prefix_route(const struct in6_addr *pfx, + int plen, + const struct net_device *dev, + u32 flags, u32 noflags, + bool no_gw) +{ + return addrconf_get_prefix_route_by_table(pfx, plen, dev, flags, noflags, no_gw, RT6_TABLE_PREFIX); +} /* Create "default" multicast route to the interface */ @@ -2689,6 +2755,10 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len, bool sllao) { + return addrconf_prefix_rcv_by_table(dev, opt, len, sllao, RT6_TABLE_PREFIX); +} +void addrconf_prefix_rcv_by_table(struct net_device *dev, u8 *opt, int len, bool sllao, u32 table_id) +{ struct prefix_info *pinfo; __u32 valid_lft; __u32 prefered_lft; @@ -2752,11 +2822,11 @@ if (addrconf_finite_timeout(rt_expires)) rt_expires *= HZ; - rt = addrconf_get_prefix_route(&pinfo->prefix, + rt = addrconf_get_prefix_route_by_table(&pinfo->prefix, pinfo->prefix_len, dev, RTF_ADDRCONF | RTF_PREFIX_RT, - RTF_DEFAULT, true); + RTF_DEFAULT, true, table_id); if (rt) { /* Autoconf prefix route */ @@ -2777,16 +2847,16 @@ flags |= RTF_EXPIRES; expires = jiffies_to_clock_t(rt_expires); } - addrconf_prefix_route(&pinfo->prefix, pinfo->prefix_len, + addrconf_prefix_route_by_table(&pinfo->prefix, pinfo->prefix_len, 0, dev, expires, flags, - GFP_ATOMIC); + GFP_ATOMIC, table_id); } fib6_info_release(rt); } /* Try to figure out our local address for this prefix */ - if (pinfo->autoconf && in6_dev->cnf.autoconf) { + if (pinfo->autoconf && in6_dev->cnf.autoconf && in6_dev->cnf.accept_ra_pinfo_autoconf) { struct in6_addr addr; bool tokenized = false, dev_addr_generated = false; @@ -3037,6 +3107,17 @@ ipv6_mc_config(net->ipv6.mc_autojoin_sk, false, pfx, dev->ifindex); } +#ifdef CONFIG_INTEL_KERNEL_FORCE_IPV6_DOWN_WHEN_NO_ADDRES + /*Added this code in order to avoid transmit messages over + IPv6 w/o receiving DHCP Advertisment messages*/ + /* If the last address is deleted administratively, + disable IPv6 on this interface. + */ + if (list_empty(&idev->addr_list)) + { + addrconf_ifdown(idev->dev, 1); + } +#endif return 0; } } @@ -3383,6 +3464,16 @@ if (IS_ERR(idev)) return; +#ifdef CONFIG_INTEL_DEFAULT_IPV6_AUTOCONF_DISABLES_IPV6_AUTOCONF + /* NETDK: Check if autoconfiguration is enabled for the network device or + * not? */ + if (idev->cnf.autoconf == 0) + { + printk ("Autoconfiguration disabled for %s\n", dev->name); + return; + } +#endif + /* this device type has no EUI support */ if (dev->type == ARPHRD_NONE && idev->cnf.addr_gen_mode == IN6_ADDR_GEN_MODE_EUI64) @@ -5516,6 +5607,7 @@ array[DEVCONF_HOPLIMIT] = cnf->hop_limit; array[DEVCONF_MTU6] = cnf->mtu6; array[DEVCONF_ACCEPT_RA] = cnf->accept_ra; + array[DEVCONF_ACCEPT_RA_TABLE] = cnf->accept_ra_table; array[DEVCONF_ACCEPT_REDIRECTS] = cnf->accept_redirects; array[DEVCONF_AUTOCONF] = cnf->autoconf; array[DEVCONF_DAD_TRANSMITS] = cnf->dad_transmits; @@ -5541,6 +5633,7 @@ array[DEVCONF_RA_DEFRTR_METRIC] = cnf->ra_defrtr_metric; array[DEVCONF_ACCEPT_RA_MIN_HOP_LIMIT] = cnf->accept_ra_min_hop_limit; array[DEVCONF_ACCEPT_RA_PINFO] = cnf->accept_ra_pinfo; + array[DEVCONF_ACCEPT_RA_PINFO_AUTOCONF] = cnf->accept_ra_pinfo_autoconf; #ifdef CONFIG_IPV6_ROUTER_PREF array[DEVCONF_ACCEPT_RA_RTR_PREF] = cnf->accept_ra_rtr_pref; array[DEVCONF_RTR_PROBE_INTERVAL] = @@ -6641,6 +6734,13 @@ .proc_handler = proc_dointvec, }, { + .procname = "accept_ra_table", + .data = &ipv6_devconf.accept_ra_table, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec, + }, + { .procname = "accept_redirects", .data = &ipv6_devconf.accept_redirects, .maxlen = sizeof(int), @@ -6784,6 +6884,13 @@ .mode = 0644, .proc_handler = proc_dointvec, }, + { + .procname = "accept_ra_pinfo_autoconf", + .data = &ipv6_devconf.accept_ra_pinfo_autoconf, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec, + }, #ifdef CONFIG_IPV6_ROUTER_PREF { .procname = "accept_ra_rtr_pref", @@ -7360,3 +7467,5 @@ destroy_workqueue(addrconf_wq); } + +EXPORT_SYMBOL(intel_ipv6_ns_filter); \ No newline at end of file