IPVS源代码分析----发送函数的实现

发送方法是在钩子函数里面,处理完包之后,调用的发包函数。根据采用的不同的策略:nat\tunnel\dr,有三种不同的发送函数。另外bypass不属于LVS负载均衡处理的范畴。
NAT部分只是修改目的地址,不修改端口号。
tunnel部分是添加一个新的IP头部
dr目的地址也不修改。
发送时,都要先查找路由。

NAT发送只发送请求方向的数据,因此是进行目的NAT。dnat_handler是在ip_vs_nat_xmit中调用的。snat_handler 是在handler_response中调用的。在这两个handler中,会调用到app层的packet in 和 packet out 函数。
int ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp)
{
      struct rtable *rt;              /* Route to the other host */
      int mtu;
      struct iphdr *iph = skb->nh.iph;
      //如果连接标志了客户端端口为0,将当前skb中的端口填给连接
      if (unlikely(cp->flags & IP_VS_CONN_F_NO_CPORT)) {
            __u16 _pt, *p;
            p = skb_header_pointer(skb, iph->ihl*4, sizeof(_pt), &_pt);
            if (p == NULL)
                  goto tx_error;

            ip_vs_conn_fill_cport(cp, *p);// *p是源端口
            IP_VS_DBG(10, "filled cport=%d\n", ntohs(*p));
      }
      //查找路由,找不到的话发ICMP出错包
      if (!(rt = __ip_vs_get_out_rt(cp, RT_TOS(iph->tos))))
            goto tx_error_icmp;

      //检查路由发出网卡的MTU,如果包长超过MTU又有DF标志,发送ICMP错误信息,而不进行分片操作
      mtu = dst_mtu(&rt->u.dst);
      if ((skb->len > mtu) && (iph->frag_off&__constant_htons(IP_DF))) {
            ip_rt_put(rt);
            icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu));
            IP_VS_DBG_RL_PKT(0, pp, skb, 0, "ip_vs_nat_xmit(): frag needed for");
            goto tx_error;
      }
      //让skb包的IP头部分是可写的
      if (!ip_vs_make_skb_writable(&skb, sizeof(struct iphdr)))
            goto tx_error_put;

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值