当前位置: 代码迷 >> 综合 >> IPv4相关PRE_ROUTING hook
  详细解决方案

IPv4相关PRE_ROUTING hook

热度:61   发布时间:2024-02-12 07:58:26.0
  • ipv4_rcv

    static int ipv4_rcv(struct rte_mbuf *mbuf, struct netif_port *port)
    {...//执行INET_HOOK_PRE_ROUTING hook点处处理函数,内部会根据不同转发模式进行相应的判定//ACCPT|STOP时执行ipv4_rcv_fin,继续往上处理//STOLEN时整个数据包处理流程结束,不再往上传递//DROP时,直接丢弃数据后返回return INET_HOOK(AF_INET, INET_HOOK_PRE_ROUTING,mbuf, port, NULL, ipv4_rcv_fin);
    }
    
  • lvs中ipv4相关hook处理函数

    static struct inet_hook_ops dp_vs_ops[] = {{.af         = AF_INET,.hook       = dp_vs_in,.hooknum    = INET_HOOK_PRE_ROUTING,.priority   = 100,},{.af         = AF_INET,.hook       = dp_vs_pre_routing,.hooknum    = INET_HOOK_PRE_ROUTING,.priority   = 99,},...
    };
    
    • 此处在PRE_ROUTING时按照优先级排序为dp_vs_pre_routing ,dp_vs_in
  • dp_vs_fill_iphdr

    //内部使用iphdr,兼顾ipv4和ipv6
    struct dp_vs_iphdr {//协议族int             af;//IP层数据头长度int             len;//传输层协议类型uint8_t         proto;//源,目的地址union inet_addr saddr;union inet_addr daddr;
    };
    static inline int dp_vs_fill_iphdr(int af, struct rte_mbuf *mbuf,struct dp_vs_iphdr *iph)
    {if (af == AF_INET){struct ipv4_hdr *ip4h = ip4_hdr(mbuf);iph->af              = AF_INET;iph->len             = ip4_hdrlen(mbuf);iph->proto           = ip4h->next_proto_id;iph->saddr.in.s_addr = ip4h->src_addr;iph->daddr.in.s_addr = ip4h->dst_addr;}else if (af == AF_INET6){struct ip6_hdr *ip6h   = ip6_hdr(mbuf);uint8_t         ip6nxt = ip6h->ip6_nxt;iph->af        = AF_INET6;iph->len       = ip6_skip_exthdr(mbuf, sizeof(struct ip6_hdr), &ip6nxt);iph->proto     = ip6nxt;iph->saddr.in6 = ip6h->ip6_src;iph->daddr.in6 = ip6h->ip6_dst;}else{return(EDPVS_NOTSUPP);}return(EDPVS_OK);
    }
    
    • dp_vs_pre_routing

      • 包裹函数,内部调用__dp_vs_pre_routing,指定协议族为AF_INET
      static int dp_vs_pre_routing(void *priv, struct rte_mbuf *mbuf,const struct inet_hook_state *state)
      {return(__dp_vs_pre_routing(priv, mbuf, state, AF_INET));
      }
      
    • __dp_vs_pre_routing

      static int __dp_vs_pre_routing(void *priv, struct rte_mbuf *mbuf,const struct inet_hook_state *state, int af)
      {struct dp_vs_iphdr    iph;struct dp_vs_service *svc;//解析填充内部使用dp_vs_iphdrif (EDPVS_OK != dp_vs_fill_iphdr(af, mbuf, &iph)){return(INET_ACCEPT);}/* Drop all ip fragment except ospf *///丢弃所有的ipv4分片数据包if ((af == AF_INET) && ip4_is_frag(ip4_hdr(mbuf))){//更新统计信息dp_vs_estats_inc(DEFENCE_IP_FRAG_DROP);return(INET_DROP);}/* Drop udp packet which send to tcp-vip *///丢弃发送至tcp-vip的udp数据if (g_defence_udp_drop && IPPROTO_UDP == iph.proto){if ((svc = dp_vs_vip_lookup(af, IPPROTO_UDP, &iph.daddr, rte_lcore_id())) == NULL){if ((svc = dp_vs_vip_lookup(af, IPPROTO_TCP, &iph.daddr, rte_lcore_id())) != NULL){dp_vs_estats_inc(DEFENCE_UDP_DROP);return(INET_DROP);}}}/* Synproxy: defence synflood *///syn_proxy功能,syn cookies相关,与lvs转发模式有关if (IPPROTO_TCP == iph.proto){int v = INET_ACCEPT;if (0 == dp_vs_synproxy_syn_rcv(af, mbuf, &iph, &v)){return(v);}}return(INET_ACCEPT);
      }
      
    • dp_vs_in

      • 包裹函数,内部指定协议族AF_INET调用__dp_vs_in
      static int dp_vs_in(void *priv, struct rte_mbuf *mbuf,const struct inet_hook_state *state)
      {return(__dp_vs_in(priv, mbuf, state, AF_INET));
      }
      
    • __dp_vs_in

      • 开始进入lvs模块,后面文章中分析
  相关解决方案