/* This is one larger than the largest protocol value that can be 

  * found in an ipv4 or ipv6 header.  Since in both cases the protocol 

  * value is presented in a __u8, this is defined to be 256. 

  */ 

 #define MAX_INET_PROTOS 
 256 



 /* This is used to register protocols. */ 

 struct net_protocol { 

void 
 (*early_demux)(struct sk_buff *skb); 

int 
 (*handler)(struct sk_buff *skb); 

void 
 (*err_handler)(struct sk_buff *skb, u32 info); 

unsigned int 
  no_policy:1, 

netns_ok:1, 

/* does the protocol do more stringent 

* icmp tag validation than simple 

* socket lookup? 

*/ 

icmp_strict_tag_validation:1; 
};
const struct net_protocol  *inet_protos[MAX_INET_PROTOS];
int inet_add_protocol(const struct net_protocol *prot, unsigned char protocol)
 {
if (!prot->netns_ok) {
pr_err("Protocol %u is not namespace aware, cannot register.\n",
protocol);
return -EINVAL;
}


return !cmpxchg((const struct net_protocol **)&inet_protos[protocol],
NULL, prot) ? 0 : -1;
 }
 EXPORT_SYMBOL(inet_add_protocol);
int inet_del_protocol(const struct net_protocol *prot, unsigned char protocol)
 {
int ret;


ret = (cmpxchg((const struct net_protocol **)&inet_protos[protocol],
      prot, NULL) == prot) ? 0 : -1;


synchronize_net();


return ret;
 }
 EXPORT_SYMBOL(inet_del_protocol);
inet_add_protocol(&icmp_protocol, IPPROTO_ICMP)
inet_add_protocol(&udp_protocol, IPPROTO_UDP)
inet_add_protocol(&tcp_protocol, IPPROTO_TCP)
inet_add_protocol(&igmp_protocol, IPPROTO_IGMP)
inet_add_protocol(&net_gre_protocol, IPPROTO_GRE)
inet_add_protocol(&pim_protocol, IPPROTO_PIM)
inet_add_protocol(&dccp_v4_protocol, IPPROTO_DCCP)
inet_add_protocol(&l2tp_ip_protocol, IPPROTO_L2TP)
inet_add_protocol(&sctp_protocol, IPPROTO_SCTP)
inet_add_protocol(&tunnel4_protocol, IPPROTO_IPIP)
inet_add_protocol(&tunnel64_protocol, IPPROTO_IPV6)