📄 ipsec_tunnel.c
字号:
stats->tx_errors++; goto cleanup; } #ifdef NET_21 skb->nh.raw = skb->data;#else /* NET_21 */ skb->ip_hdr = skb->h.iph = (struct iphdr *) skb->data;#endif /* NET_21 */ iph->check = 0; iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl); KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, "klips_debug:ipsec_tunnel_start_xmit: " "after <%s%s%s>, SA:%s:\n", TDB_XFORM_NAME(tdbp), sa_len ? sa : " (error)"); KLIPS_IP_PRINT(debug_tunnel & DB_TN_XMIT, iph); tdbp->tdb_lifetime_bytes_c += len; if(!tdbp->tdb_lifetime_usetime_c) { tdbp->tdb_lifetime_usetime_c = jiffies / HZ; } tdbp->tdb_lifetime_usetime_l = jiffies / HZ; tdbp->tdb_lifetime_packets_c += 1; tdbprev = tdbp; tdbp = tdbp->tdb_onext; } /* end encapsulation loop here XXX */ spin_unlock(&tdb_lock); matcher.sen_ip_src.s_addr = iph->saddr; matcher.sen_ip_dst.s_addr = iph->daddr; spin_lock(&eroute_lock); er = ipsec_findroute(&matcher); if(er) { outgoing_said = er->er_said; eroute_pid = er->er_pid; er->er_count++; er->er_lasttime = jiffies/HZ; } spin_unlock(&eroute_lock); KLIPS_PRINT((debug_tunnel & DB_TN_XMIT) && /* ((orgdst != newdst) || (orgsrc != newsrc)) */ (orgedst != outgoing_said.dst.s_addr) && outgoing_said.dst.s_addr && er, "klips_debug:ipsec_tunnel_start_xmit: " "We are recursing here.\n"); } while(/*((orgdst != newdst) || (orgsrc != newsrc))*/ (orgedst != outgoing_said.dst.s_addr) && outgoing_said.dst.s_addr && er); KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, "klips_debug:ipsec_tunnel_start_xmit: " "After recursive xforms -- head,tailroom: %d,%d\n", skb_headroom(skb), skb_tailroom(skb)); if(sysctl_ipsec_icmp && (innersrc != newsrc) && (ntohs(iph->tot_len) > physmtu)) { ICMP_SEND(oskb ? oskb : skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, prv->mtu, physdev); KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, "klips_debug:ipsec_tunnel_start_xmit: " "IPSEC tunnel mode packet is larger than MTU, ICMP sent.\n"); } if(saved_header) { if(skb_headroom(skb) < hard_header_len) { printk(KERN_WARNING "klips_error:ipsec_tunnel_start_xmit: " "tried to skb_push hhlen=%d, %d available. This should never happen, please report.\n", hard_header_len, skb_headroom(skb)); stats->tx_errors++; goto cleanup; } skb_push(skb, hard_header_len); for (i = 0; i < hard_header_len; i++) { skb->data[i] = saved_header[i]; } } bypass: KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, "klips_debug:ipsec_tunnel_start_xmit: " "With hard_header, final head,tailroom: %d,%d\n", skb_headroom(skb), skb_tailroom(skb));#ifdef NET_21 /* 2.2 and 2.4 kernels */ /* new route/dst cache code from James Morris */ skb->dev = physdev; /*skb_orphan(skb);*/ if((error = ip_route_output(&rt, skb->nh.iph->daddr, pass ? 0 : skb->nh.iph->saddr, RT_TOS(skb->nh.iph->tos), physdev->iflink))) { stats->tx_errors++; KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, "klips_debug:ipsec_tunnel_start_xmit: " "ip_route_output failed with error code %d, rt->u.dst.dev=%s, dropped\n", error, rt->u.dst.dev->name); goto cleanup; } if(dev == rt->u.dst.dev) { ip_rt_put(rt); /* This is recursion, drop it. */ stats->tx_errors++; KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, "klips_debug:ipsec_tunnel_start_xmit: " "suspect recursion, dev=rt->u.dst.dev=%s, dropped\n", dev->name); goto cleanup; } dst_release(skb->dst); skb->dst = &rt->u.dst; stats->tx_bytes += skb->len; if(skb->len < skb->nh.raw - skb->data) { stats->tx_errors++; printk(KERN_WARNING "klips_error:ipsec_tunnel_start_xmit: " "tried to __skb_pull nh-data=%d, %d available. This should never happen, please report.\n", skb->nh.raw - skb->data, skb->len); goto cleanup; } __skb_pull(skb, skb->nh.raw - skb->data);#ifdef SKB_RESET_NFCT nf_conntrack_put(skb->nfct); skb->nfct = NULL;#ifdef CONFIG_NETFILTER_DEBUG skb->nf_debug = 0;#endif /* CONFIG_NETFILTER_DEBUG */#endif /* SKB_RESET_NFCT */ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, "klips_debug:ipsec_tunnel_start_xmit: " "...done, calling ip_send() on device:%s\n", skb->dev ? skb->dev->name : "NULL"); KLIPS_IP_PRINT(debug_tunnel & DB_TN_XMIT, skb->nh.iph);#ifdef NETDEV_23 /* 2.4 kernels */ { int err; err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev, ipsec_tunnel_xmit2); if(err != NET_XMIT_SUCCESS && err != NET_XMIT_CN) { if(net_ratelimit()) printk(KERN_ERR "klips_error:ipsec_tunnel_start_xmit: " "ip_send() failed, err=%d\n", -err); stats->tx_errors++; stats->tx_aborted_errors++; skb = NULL; goto cleanup; } }#else /* NETDEV_23 */ /* 2.2 kernels */ ip_send(skb);#endif /* NETDEV_23 */#else /* NET_21 */ /* 2.0 kernels */ skb->arp = 1; /* ISDN/ASYNC PPP from Matjaz Godec. */ /* skb->protocol = htons(ETH_P_IP); */ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, "klips_debug:ipsec_tunnel_start_xmit: " "...done, calling dev_queue_xmit() or ip_fragment().\n"); IP_SEND(skb, physdev);#endif /* NET_21 */ stats->tx_packets++; skb = NULL; cleanup:#if defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) netif_wake_queue(dev);#else /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */ dev->tbusy = 0;#endif /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */ if(saved_header) { kfree(saved_header); } if(skb) { dev_kfree_skb(skb, FREE_WRITE); } if(oskb) { dev_kfree_skb(oskb, FREE_WRITE); } return 0;}DEBUG_NO_STATIC struct net_device_stats *ipsec_tunnel_get_stats(struct device *dev){ return &(((struct ipsecpriv *)(dev->priv))->mystats);}/* * Revectored calls. * For each of these calls, a field exists in our private structure. */DEBUG_NO_STATIC intipsec_tunnel_hard_header(struct sk_buff *skb, struct device *dev, unsigned short type, void *daddr, void *saddr, unsigned len){ struct ipsecpriv *prv = dev->priv; struct device *tmp; int ret; struct net_device_stats *stats; /* This device's statistics */ if(skb == NULL) { KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, "klips_debug:ipsec_tunnel_hard_header: " "no skb..."); return -ENODATA; } if(dev == NULL) { KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, "klips_debug:ipsec_tunnel_hard_header: " "no device..."); return -ENODEV; } KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, "klips_debug:ipsec_tunnel_hard_header: " "skb->dev=%s dev=%s.", skb->dev ? skb->dev->name : "NULL", dev->name); if(prv == NULL) { KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, "klips_debug:ipsec_tunnel_hard_header: " "no private space associated with dev=%s", dev->name ? dev->name : "NULL"); return -ENODEV; } stats = (struct net_device_stats *) &(prv->mystats); if(prv->dev == NULL) { KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, "klips_debug:ipsec_tunnel_hard_header: " "no physical device associated with dev=%s", dev->name ? dev->name : "NULL"); stats->tx_dropped++; return -ENODEV; } /* check if we have to send a IPv6 packet. It might be a Router Solicitation, where the building of the packet happens in reverse order: 1. ll hdr, 2. IPv6 hdr, 3. ICMPv6 hdr -> skb->nh.raw is still uninitialized when this function is called!! If this is no IPv6 packet, we can print debugging messages, otherwise we skip all debugging messages and just build the ll header */ if(type != ETH_P_IPV6) { /* execute this only, if we don't have to build the header for a IPv6 packet */ if(!prv->hard_header) { KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, "klips_debug:ipsec_tunnel_hard_header: " "physical device has been detached, packet dropped 0x%p->0x%p len=%d type=%d dev=%s->NULL ", saddr, daddr, len, type, dev->name);#ifdef NET_21 KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC, "ip=%08x->%08x\n", (__u32)ntohl(skb->nh.iph->saddr), (__u32)ntohl(skb->nh.iph->daddr) );#else /* NET_21 */ KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC, "ip=%08x->%08x\n", (__u32)ntohl(skb->ip_hdr->saddr), (__u32)ntohl(skb->ip_hdr->daddr) );#endif /* NET_21 */ stats->tx_dropped++; return -ENODEV; } #define da ((struct device *)(prv->dev))->dev_addr KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, "klips_debug:ipsec_tunnel_hard_header: " "Revectored 0x%p->0x%p len=%d type=%d dev=%s->%s dev_addr=%02x:%02x:%02x:%02x:%02x:%02x ", saddr, daddr, len, type, dev->name, prv->dev->name, da[0], da[1], da[2], da[3], da[4], da[5]);#ifdef NET_21 KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, "ip=%08x->%08x\n", (__u32)ntohl(skb->nh.iph->saddr), (__u32)ntohl(skb->nh.iph->daddr) );#else /* NET_21 */ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, "ip=%08x->%08x\n", (__u32)ntohl(skb->ip_hdr->saddr), (__u32)ntohl(skb->ip_hdr->daddr) );#endif /* NET_21 */ } else { KLIPS_PRINT(debug_tunnel, "klips_debug:ipsec_tunnel_hard_header: " "is IPv6 packet, skip debugging messages, only revector and build linklocal header.\n"); } tmp = skb->dev; skb->dev = prv->dev; ret = prv->hard_header(skb, prv->dev, type, (void *)daddr, (void *)saddr, len); skb->dev = tmp; return ret;}DEBUG_NO_STATIC int#ifdef NET_21ipsec_tunnel_rebuild_header(struct sk_buff *skb)#else /* NET_21 */ipsec_tunnel_rebuild_header(void *buff, struct device *dev, unsigned long raddr, struct sk_buff *skb)#endif /* NET_21 */{ struct ipsecpriv *prv = skb->dev->priv; struct device *tmp; int ret; struct net_device_stats *stats; /* This device's statistics */ if(skb->dev == NULL) { KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, "klips_debug:ipsec_tunnel_rebuild_header: " "no device..."); return -ENODEV; } if(prv == NULL) { KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, "klips_debug:ipsec_tunnel_rebuild_header: " "no private space associated with dev=%s", skb->dev->name ? skb->dev->name : "NULL"); return -ENODEV; } stats = (struct net_device_stats *) &(prv->mystats); if(prv->dev == NULL) { KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, "klips_debug:ipsec_tunnel_rebuild_header: " "no physical device associated with dev=%s", skb->dev->name ? skb->dev->name : "NULL"); stats->tx_dropped++; return -ENODEV; } if(!prv->rebuild_header) { KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, "klips_debug:ipsec_tunnel_rebuild_header: " "physical device has been detached, packet dropped skb->dev=%s->NULL ", skb->dev->name);#ifdef NET_21 KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, "ip=%08x->%08x\n", (__u32)ntohl(skb->nh.iph->saddr), (__u32)ntohl(skb->nh.iph->daddr) );#else /* NET_21 */ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, "ip=%08x->%08x\n", (__u32)ntohl(skb->ip_hdr->saddr), (__u32)ntohl(skb->ip_hdr->daddr) );#endif /* NET_21 */ stats->tx_dropped++; return -ENODEV; } KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, "klips_debug:ipsec_tunnel: " "Revectored rebuild_header dev=%s->%s ", skb->dev->name, prv->dev->name);#ifdef NET_21 KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, "ip=%08x->%08x\n", (__u32)ntohl(skb->nh.iph->saddr), (__u32)ntohl(skb->nh.iph->daddr) );#else /* NET_21 */ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, "ip=%08x->%08x\n", (__u32)ntohl(skb->ip_hdr->saddr), (__u32)ntohl(skb->ip_hdr->daddr) );#endif /* NET_21 */ tmp = skb->dev; skb->dev = prv->dev; #ifdef NET_21 ret = prv->rebuild_header(skb);#else /* NET_21 */ ret = prv->rebuild_header(buff, prv->dev, raddr, skb);#endif /* NET_21 */ skb->dev = tmp; return ret;}DEBUG_NO_STATIC intipsec_tunnel_set_mac_address(struct device *dev, void *addr){ struct ipsecpriv *prv = dev->priv; struct net_device_stats *stats; /* This device's statistics */ if(dev == NULL) { KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, "klips_debug:ipsec_tunnel_set_mac_address: " "no device..."); return -ENODEV; } if(prv == NULL) { KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, "klips_debug:ipsec_tunnel_set_mac_address: " "no private space associated with dev=%s", dev->name ? dev->name : "NULL"); return -E
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -