static int ip_local_deliver_finish(struct sk_buff *skb) { struct net *net = dev_net(skb->dev); __skb_pull(skb, ip_hdrlen(skb)); /* Point into the IP datagram, just past the header. */ skb_reset_transport_header(skb); rcu_read_lock(); { int protocol = ip_hdr(skb)->protocol; int hash, raw; struct net_protocol *ipprot; resubmit: raw = raw_local_deliver(skb, protocol); hash = protocol & (MAX_INET_PROTOS - 1); ipprot = rcu_dereference(inet_protos[hash]); if (ipprot != NULL && (net == &init_net || ipprot->netns_ok)) { int ret; if (!ipprot->no_policy) { if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) { kfree_skb(skb); goto out; } nf_reset(skb); } ret = ipprot->handler(skb); if (ret < 0) { protocol = -ret; goto resubmit; } IP_INC_STATS_BH(net, IPSTATS_MIB_INDELIVERS); } else { if (!raw) { if (xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) { IP_INC_STATS_BH(net, IPSTATS_MIB_INUNKNOWNPROTOS); icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PROT_UNREACH, 0); } } else IP_INC_STATS_BH(net, IPSTATS_MIB_INDELIVERS); kfree_skb(skb); } } out: rcu_read_unlock(); return 0; }
static int ip_local_deliver_finish(struct sk_buff *skb) { struct net *net = dev_net(skb->dev); __skb_pull(skb, skb_network_header_len(skb)); rcu_read_lock(); { int protocol = ip_hdr(skb)->protocol; const struct net_protocol *ipprot; int raw; resubmit: raw = raw_local_deliver(skb, protocol); ipprot = rcu_dereference(inet_protos[protocol]); if (ipprot != NULL) { int ret; if (!ipprot->no_policy) { if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) { kfree_skb(skb); goto out; } nf_reset(skb); } ret = ipprot->handler(skb); if (ret < 0) { protocol = -ret; goto resubmit; } IP_INC_STATS_BH(net, IPSTATS_MIB_INDELIVERS); } else { if (!raw) { if (xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) { IP_INC_STATS_BH(net, IPSTATS_MIB_INUNKNOWNPROTOS); icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PROT_UNREACH, 0); } kfree_skb(skb); } else { IP_INC_STATS_BH(net, IPSTATS_MIB_INDELIVERS); consume_skb(skb); } } } out: rcu_read_unlock(); return 0; }
static inline int ip_local_deliver_finish2(struct sk_buff *skb, u_int8_t protocol) { struct vrf *vrf = if_dev_vrf(skb->dev); rcu_read_lock(); { /* Note: See raw.c and net/raw.h, RAWV4_HTABLE_SIZE==MAX_INET_PROTOS */ //int protocol = skb->nh.iph->protocol; int hash, raw; struct net_protocol *ipprot; resubmit: raw = raw_local_deliver(skb, protocol); hash = protocol & (MAX_INET_PROTOS - 1); if ((ipprot = rcu_dereference(inet_protos[hash])) != NULL) { int ret; if (!ipprot->no_policy) { if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) { kfree_skb(skb); goto out; } nf_reset(skb); ns_reset(skb); } ret = ipprot->handler(skb); if (ret < 0) { protocol = -ret; goto resubmit; } IP_INC_STATS_BH(vrf, IPSTATS_MIB_INDELIVERS); } else { if (!raw) { if (xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) { IP_INC_STATS_BH(vrf, IPSTATS_MIB_INUNKNOWNPROTOS); icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PROT_UNREACH, 0); } } else IP_INC_STATS_BH(vrf, IPSTATS_MIB_INDELIVERS); kfree_skb(skb); } } out: rcu_read_unlock(); return 0; }
int ip_local_deliver_finish(struct sk_buff *skb) { int ihl = skb->nh.iph->ihl*4; struct nf_conn *ct = (struct nf_conn *)skb->nfct; struct vrf *vrf = if_dev_vrf(skb->dev); __skb_pull(skb, ihl); skb->h.raw = skb->data; if(ipsec_data_packet(skb)) { return ipsec_receive_skb(skb); } /* 上送本机的报文,若经过流分类,则需要下发快转表项 如果是ipsec数据报文则不需要下发快转表,数据报文会在后面 下发快转表*/ if (ct && test_bit(IPS_CONFIRMED_BIT, &ct->status)) { if (0 == smp_processor_id ()) { NF_GET_CPU(ct) = 0; } if(ipsec_udp_float_packet(skb)) { skb->ff_flag = ff_set_flag(skb, DRV_FF_FLAG_IPSEC_DPCRYPT); skb->ff_flag = ff_clr_flag(skb, DRV_FF_FLAG_LINUX); } else { skb->ff_flag = ff_set_flag(skb, DRV_FF_FLAG_LINUX); } if(nf_ct_tcp_loose) { ff_items_add_for_simple_state(skb); } else { ff_items_add_basic_on_session(skb); } } if (ipsec_conn_packet(skb)) { #ifdef CONFIG_NETSESSION struct net_session *ns = (struct net_session *)(skb->ns); if(ns) { ns_ff_set_flag(skb, NS_FF_IPSEC_DPCRYPT); } #endif ipsec_pkt_send2user(skb); return 0; } rcu_read_lock(); { /* Note: See raw.c and net/raw.h, RAWV4_HTABLE_SIZE==MAX_INET_PROTOS */ int protocol = skb->nh.iph->protocol; int hash, raw; struct net_protocol *ipprot; resubmit: raw = raw_local_deliver(skb, protocol); hash = protocol & (MAX_INET_PROTOS - 1); if ((ipprot = rcu_dereference(inet_protos[hash])) != NULL) { int ret; if (!ipprot->no_policy) { if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) { kfree_skb(skb); goto out; } nf_reset(skb); ns_reset(skb); } conplat_bh_disable(); ret = ipprot->handler(skb); conplat_bh_enable(); if (ret < 0) { protocol = -ret; goto resubmit; } IP_INC_STATS_BH(vrf, IPSTATS_MIB_INDELIVERS); } else { if (!raw) { if (xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) { IP_INC_STATS_BH(vrf, IPSTATS_MIB_INUNKNOWNPROTOS); if(g_icmp_status.prot_unreach == IP_OPTION_SUPPORT) { icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PROT_UNREACH, 0); } } } else IP_INC_STATS_BH(vrf, IPSTATS_MIB_INDELIVERS); kfree_skb(skb); } } out: rcu_read_unlock(); return 0; }