--- zzzz-none-000/linux-4.9.279/net/ipv6/ip6_input.c 2021-08-08 06:38:54.000000000 +0000 +++ puma7-atom-6591-750/linux-4.9.279/net/ipv6/ip6_input.c 2023-02-08 11:43:43.000000000 +0000 @@ -18,6 +18,12 @@ * Mitsuru KANDA @USAGI and * YOSHIFUJI Hideaki @USAGI: Remove ipv6_parse_exthdrs(). */ +/* + * Includes Intel Corporation's changes/modifications dated: 2018. + * Changed/modified portions - Copyright (c) 2018, Intel Corporation. + */ + +#define pr_fmt(fmt) "IPv6: " fmt #include #include @@ -47,6 +53,8 @@ #include #include +#include + int ip6_rcv_finish(struct net *net, struct sock *sk, struct sk_buff *skb) { /* if ingress device is enslaved to an L3 master device pass the @@ -71,7 +79,7 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev) { - const struct ipv6hdr *hdr; + struct ipv6hdr *hdr; u32 pkt_len; struct inet6_dev *idev; struct net *net = dev_net(skb->dev); @@ -195,6 +203,18 @@ } } +#ifdef CONFIG_INTEL_NS_DEVICE_FILTER + if (hdr->nexthdr == IPPROTO_ICMPV6) + { + struct icmp6hdr *icmpv6_hdr; + icmpv6_hdr = icmp6_hdr(skb); + if (icmpv6_hdr->icmp6_type == NDISC_NEIGHBOUR_SOLICITATION) + { + if (intel_ns_handler (skb->dev,&(hdr->daddr),IFA_F_TENTATIVE) == 0) + goto drop; + } + } +#endif rcu_read_unlock(); /* Must drop socket now because of tproxy. */ @@ -216,7 +236,7 @@ */ -static int ip6_input_finish(struct net *net, struct sock *sk, struct sk_buff *skb) +int ip6_input_finish(struct net *net, struct sock *sk, struct sk_buff *skb) { const struct inet6_protocol *ipprot; struct inet6_dev *idev; @@ -315,7 +335,7 @@ kfree_skb(skb); return 0; } - +EXPORT_SYMBOL(ip6_input_finish); int ip6_input(struct sk_buff *skb) { @@ -404,3 +424,44 @@ return 0; } + +static void ip6_avm_pa_transmit(void *arg, struct sk_buff *skb) +{ + /* We can safely pass NULL as sk parameter, it is just required + * to be a valid netfilter hook. The initiator, ip6_input() + * passes a NULL sock because it doesn't even know the socket yet. + */ + ip6_input_finish((struct net *) arg, NULL, skb); +} + +static void __init ip6_avm_pa_register(void) +{ + struct avm_pa_dev_info *ip6_dev = AVM_PA_NET_IP6_DEVINFO(&init_net); + struct avm_pa_pid_cfg cfg = {0}; + struct avm_pa_pid_ecfg ecfg = {0}; + + if (!ip6_dev) + return; + + strlcpy(cfg.name, "ipv6", sizeof(cfg.name)); + cfg.framing = avm_pa_framing_ipdev; + cfg.default_mtu = 0xffff; + cfg.tx_func = &ip6_avm_pa_transmit; + cfg.tx_arg = &init_net; + + if (avm_pa_dev_pid_register(ip6_dev, &cfg) < 0) { + pr_err("failed to register avm_pa pid %s\n", cfg.name); + return; + } + + /* ip6_input_finish() needs a valid IP6CB */ + ecfg.version = AVM_PA_PID_ECFG_VERSION; + ecfg.cb_start = 0; + ecfg.cb_len = sizeof(struct inet6_skb_parm); + avm_pa_pid_set_ecfg(ip6_dev->pid_handle, &ecfg); +} + +void __init ip6_input_init(void) +{ + ip6_avm_pa_register(); +}