--- zzzz-none-000/linux-3.10.107/drivers/net/ppp/pppoe.c 2017-06-27 09:49:32.000000000 +0000 +++ vr9-7490-729/linux-3.10.107/drivers/net/ppp/pppoe.c 2021-11-10 11:53:55.000000000 +0000 @@ -57,6 +57,12 @@ * */ +/** + * Some part of this file is modified by Ikanos Communications. + * + * Copyright (C) 2013-2014 Ikanos Communications. + */ + #include #include #include @@ -84,12 +90,22 @@ #include #include +#if CONFIG_IPSEC_AP_SUPPORT +#include "netpro/cen.h" +#include "netpro/secap_cen.h" + +#endif #define PPPOE_HASH_BITS 4 #define PPPOE_HASH_SIZE (1 << PPPOE_HASH_BITS) #define PPPOE_HASH_MASK (PPPOE_HASH_SIZE - 1) static int __pppoe_xmit(struct sock *sk, struct sk_buff *skb); +#if defined(CONFIG_FUSIV_KERNEL_PPPOE_RELAY) || defined(CONFIG_FUSIV_KERNEL_PPPOE_RELAY_MODULE) +unsigned char gbEnablePPPoERelay = 0; +int (*relayGotDiscoveryPacket_ptr)(struct sk_buff *skb, struct net_device *dev,struct packet_type *pt)=NULL; +int (*relayGotSessionPacket_ptr)(struct sk_buff *skb,struct net_device *dev, struct packet_type *pt)=NULL; +#endif static const struct proto_ops pppoe_ops; static const struct ppp_channel_ops pppoe_chan_ops; @@ -420,6 +436,21 @@ struct pppoe_net *pn; int len; +#if defined(CONFIG_FUSIV_KERNEL_PPPOE_RELAY) || defined(CONFIG_FUSIV_KERNEL_PPPOE_RELAY_MODULE) + if(relayGotSessionPacket_ptr == NULL) + { + printk("\npppoe: pppoerelay module not initialized properly...\n"); + return NET_RX_SUCCESS; + } + + if( ( gbEnablePPPoERelay ) && ( (*relayGotSessionPacket_ptr)(skb,dev,pt) == 0) ) + { + //printk("PPPOE Relay Sess Packet : FAILURE\n"); + return NET_RX_SUCCESS; + } + else + { +#endif skb = skb_share_check(skb, GFP_ATOMIC); if (!skb) goto out; @@ -452,6 +483,9 @@ kfree_skb(skb); out: return NET_RX_DROP; +#if defined(CONFIG_FUSIV_KERNEL_PPPOE_RELAY) || defined(CONFIG_FUSIV_KERNEL_PPPOE_RELAY_MODULE) + } +#endif } /************************************************************************ @@ -468,6 +502,20 @@ struct pppox_sock *po; struct pppoe_net *pn; +#if defined(CONFIG_FUSIV_KERNEL_PPPOE_RELAY) || defined(CONFIG_FUSIV_KERNEL_PPPOE_RELAY_MODULE) + if(relayGotDiscoveryPacket_ptr == NULL) + { + printk("\npppoe: pppoerealay module not initialized properly\n"); + goto abort; + } + if( ( gbEnablePPPoERelay )&& ((*relayGotDiscoveryPacket_ptr)(skb,dev,pt) == 0)) + { + //printk("PPPOE Relay Disc packet\n"); + goto abort; + } + else + { +#endif skb = skb_share_check(skb, GFP_ATOMIC); if (!skb) goto out; @@ -506,6 +554,9 @@ kfree_skb(skb); out: return NET_RX_SUCCESS; /* Lies... :-) */ +#if defined(CONFIG_FUSIV_KERNEL_PPPOE_RELAY) || defined(CONFIG_FUSIV_KERNEL_PPPOE_RELAY_MODULE) + } +#endif } static struct packet_type pppoes_ptype __read_mostly = { @@ -849,7 +900,9 @@ goto end; - skb = sock_wmalloc(sk, total_len + dev->hard_header_len + 32, +// AVM/TKL: MERGE: Ikanos adds padding + skb = sock_wmalloc(sk, total_len + dev->hard_header_len + 32 + NET_SKB_PAD, +// skb = sock_wmalloc(sk, total_len + dev->hard_header_len + 32, 0, GFP_KERNEL); if (!skb) { error = -ENOMEM; @@ -857,7 +910,9 @@ } /* Reserve space for headers. */ - skb_reserve(skb, dev->hard_header_len); +// AVM/TKL: MERGE: Ikanos adds padding + skb_reserve(skb, dev->hard_header_len + NET_SKB_PAD); +// skb_reserve(skb, dev->hard_header_len); skb_reset_network_header(skb); skb->dev = dev; @@ -900,7 +955,9 @@ struct net_device *dev = po->pppoe_dev; struct pppoe_hdr *ph; int data_len = skb->len; - +#if CONFIG_IPSEC_AP_SUPPORT + int ivlen=0,padlen=0,data_len1=0; +#endif /* The higher-level PPP code (ppp_unregister_channel()) ensures the PPP * xmit operations conclude prior to an unregistration call. Thus * sk->sk_state cannot change, so we don't need to do lock_sock(). @@ -929,7 +986,39 @@ ph->type = 1; ph->code = 0; ph->sid = po->num; +#if CONFIG_IPSEC_AP_SUPPORT + data_len1 = data_len; +#if DEBUG + printk("\r\n%s[%d] data_len1 = %d\n",__func__,__LINE__,data_len1); +#endif + if (skb->apFlowData.encap_protocol == PROCESS_ESP_ENCAP) + { + apSa_t * pApSa = (apSa_t *) skb->apFlowData.pSA; + ivlen = pApSa->cryptoOperation.ucIvLength; + /* Considering ESP Transport mode only and L2TP over IPsec mode */ + if((pApSa->cryptoOperation.eSecapOp == SECAP_ESP_TRANSPORT_OUTGOING_FLOW) || + (pApSa->cryptoOperation.eSecapOp == SECAP_L2TP_OUTGOING_FLOW)) + { + padlen = (data_len1 - 2 + ESP_PADLEN_PROTO_FLDS_SIZE - IPV4_HDR_LEN)%ivlen; + } + else + padlen = (data_len1 - 2 + ESP_PADLEN_PROTO_FLDS_SIZE)%ivlen; + + if (padlen) + padlen = ivlen - padlen; + + data_len1 += pApSa->uctunHdrLen + ESP_PADLEN_PROTO_FLDS_SIZE; + data_len1 += padlen+pApSa->cryptoOperation.ucIcvTruncLength; +#if DEBUG + printk("\r\n%s[%d] \nuctunHdrlen = %d\n data_len1 = %d\n ICV = %d\n padlen = %d\n ivlen=%d\n SecapOp=%d\n", \ + __func__,__LINE__,pApSa->uctunHdrLen,data_len1,pApSa->cryptoOperation.ucIcvTruncLength,padlen, \ + ivlen, pApSa->cryptoOperation.eSecapOp); +#endif + } + ph->length = htons(data_len1); +#else ph->length = htons(data_len); +#endif skb->protocol = cpu_to_be16(ETH_P_PPP_SES); skb->dev = dev; @@ -1192,6 +1281,68 @@ unregister_pernet_device(&pppoe_net_ops); } +// AVM/TKL: MERGE no condition in Ikanos source +#if defined(CONFIG_MACH_FUSIV) +int isPPPModTypePPPoE(struct ppp_channel *pppchan) +{ + if ((pppchan->ops) && + (pppchan->ops->start_xmit) && + (pppchan->ops->start_xmit == pppoe_xmit)) + return 1; + + return 0; +} + +char *getPPPoEIfName(struct ppp_channel *pppchan) +{ + struct sock *sk = (struct sock *) pppchan->private; + struct pppox_sock *po; + + if (!sk) + return NULL; + + po = pppox_sk(sk); + + if (!po) + return NULL; + + if (po->pppoe_dev) + return po->pppoe_dev->name; + + return NULL; +} + +int getPPPoESessIdAndAddr(struct ppp_channel *pppchan, unsigned char *addr) +{ + struct sock *sk = (struct sock *) pppchan->private; + struct pppox_sock *po; + int result; + + if (!sk) + return 0; + + po = pppox_sk(sk); + + if (!po) + return 0; + + for (result = 0; result < 6; result++) + addr[result] = po->pppoe_pa.remote[result]; + + return po->pppoe_pa.sid; +} + +EXPORT_SYMBOL(isPPPModTypePPPoE); +EXPORT_SYMBOL(getPPPoEIfName); +EXPORT_SYMBOL(getPPPoESessIdAndAddr); + +#if defined(CONFIG_FUSIV_KERNEL_PPPOE_RELAY) || defined(CONFIG_FUSIV_KERNEL_PPPOE_RELAY_MODULE) +EXPORT_SYMBOL(gbEnablePPPoERelay); +EXPORT_SYMBOL(relayGotDiscoveryPacket_ptr); +EXPORT_SYMBOL(relayGotSessionPacket_ptr); +#endif +#endif // CONFIG_MACH_FUSIV + module_init(pppoe_init); module_exit(pppoe_exit);