发送IP封包到高层协议

来源:互联网 发布:大数据hadoop 编辑:程序博客网 时间:2024/05/17 22:54
int ip_local_deliver(struct sk_buff *skb)
{
/*
* Reassemble IP fragments.
*/
struct net *net = dev_net(skb->dev);


if (ip_is_fragment(ip_hdr(skb))) {
if (ip_defrag(net, skb, IP_DEFRAG_LOCAL_DELIVER))
return 0;
}


return NF_HOOK(NFPROTO_IPV4, NF_INET_LOCAL_IN,
      net, NULL, skb, skb->dev, NULL,
      ip_local_deliver_finish);

}




struct rtable *rt_dst_alloc(struct net_device *dev,
   unsigned int flags, u16 type,
   bool nopolicy, bool noxfrm, bool will_cache)
{
struct rtable *rt;


rt = dst_alloc(&ipv4_dst_ops, dev, 1, DST_OBSOLETE_FORCE_CHK,
      (will_cache ? 0 : (DST_HOST | DST_NOCACHE)) |
      (nopolicy ? DST_NOPOLICY : 0) |
      (noxfrm ? DST_NOXFRM : 0));


if (rt) {
rt->rt_genid = rt_genid_ipv4(dev_net(dev));
rt->rt_flags = flags;
rt->rt_type = type;
rt->rt_is_input = 0;
rt->rt_iif = 0;
rt->rt_pmtu = 0;
rt->rt_gateway = 0;
rt->rt_uses_gateway = 0;
rt->rt_table_id = 0;
INIT_LIST_HEAD(&rt->rt_uncached);


rt->dst.output = ip_output;
if (flags & RTCF_LOCAL)
rt->dst.input = ip_local_deliver;
}


return rt;
}




static int ip_local_deliver_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
{
__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) {
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(net, IPSTATS_MIB_INDELIVERS);
} else {
if (!raw) {
if (xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) {
__IP_INC_STATS(net, IPSTATS_MIB_INUNKNOWNPROTOS);
icmp_send(skb, ICMP_DEST_UNREACH,
 ICMP_PROT_UNREACH, 0);
}
kfree_skb(skb);
} else {
__IP_INC_STATS(net, IPSTATS_MIB_INDELIVERS);
consume_skb(skb);
}
}
}
 out:
rcu_read_unlock();


return 0;
}


static const struct net_protocol tcp_protocol = {
.early_demux = tcp_v4_early_demux,
.handler= tcp_v4_rcv,
.err_handler = tcp_v4_err,
.no_policy = 1,
.netns_ok = 1,
.icmp_strict_tag_validation = 1,
};


static const struct net_protocol udp_protocol = {
.early_demux =udp_v4_early_demux,
.handler =udp_rcv,
.err_handler =udp_err,
.no_policy = 1,
.netns_ok = 1,
};


static const struct net_protocol icmp_protocol = {
.handler =icmp_rcv,
.err_handler =icmp_err,
.no_policy = 1,
.netns_ok = 1,
};



0 0
原创粉丝点击