IPv4相关PRE_ROUTING hook

  • 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_iphdr
          if (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模块,后面文章中分析
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: BAPI_ROUTING_CREATE是一个SAP提供的用于创建工艺路线的BAPI。使用BAPI_ROUTING_CREATE可以通过编程的方式,在SAP系统中创建工艺路线。 使用BAPI_ROUTING_CREATE创建工艺路线的步骤如下: 1. 准备数据:需要准备工厂代码、物料号、工艺路线的版本号、工艺路线描述等必要的信息,同时需要准备工序、工作中心、组件等工艺路线的详细信息。 2. 调用BAPI_ROUTING_CREATE:使用SAP的RFC函数模块来调用BAPI_ROUTING_CREATE,将准备好的数据作为输入参数传递给BAPI_ROUTING_CREATE。BAPI_ROUTING_CREATE会根据输入参数创建工艺路线。 3. 处理返回值:BAPI_ROUTING_CREATE会返回创建后的工艺路线的版本号等信息,需要对返回值进行处理,判断是否创建成功。 以下是一个简单的示例代码,用于使用BAPI_ROUTING_CREATE创建SAP工艺路线: ``` DATA: lt_routing_operation TYPE STANDARD TABLE OF bapi_routing_operation, ls_routing_operation LIKE LINE OF lt_routing_operation, lt_routing_header TYPE STANDARD TABLE OF bapi_routing_header, ls_routing_header LIKE LINE OF lt_routing_header. * 准备工艺路线数据 ls_routing_header-material = 'MAT001'. ls_routing_header-plant = '1000'. ls_routing_header-routing_group = '001'. ls_routing_header-routing_group_counter = '01'. APPEND ls_routing_header TO lt_routing_header. ls_routing_operation-operation = '0010'. ls_routing_operation-work_center = 'WC001'. ls_routing_operation-component = 'MAT001'. ls_routing_operation-component_qty = '1.0'. APPEND ls_routing_operation TO lt_routing_operation. * 调用BAPI_ROUTING_CREATE CALL FUNCTION 'BAPI_ROUTING_CREATE' EXPORTING routing_header = ls_routing_header client = sy-mandt TABLES routing_operation = lt_routing_operation EXCEPTIONS error_during_update = 1 OTHERS = 2. IF sy-subrc <> 0. MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4. ENDIF. ``` 在这个示例代码中,我们首先准备了工艺路线的数据,然后调用BAPI_ROUTING_CREATE进行创建。请注意,在实际使用中,需要根据具体情况对代码进行修改。 ### 回答2: BAPI_ROUTING_CREATE是一个SAP系统中用于创建工艺路线的标准函数模块。它可以通过编程的方式,将新的工艺路线信息导入到SAP系统中。 使用BAPI_ROUTING_CREATE函数模块,首先需要传入一些必要的参数。比如说,我们需要提供工艺路线的版本号、物料号和工厂代码。这些信息需要提前准备好,并作为输入参数传递给函数模块。 在调用BAPI_ROUTING_CREATE函数模块之后,系统将根据传入的参数创建一条新的工艺路线。在创建过程中,我们可以设置一些相关的属性,比如工序的顺序、工作中心、耗时等。这些属性也需要作为函数模块的输入参数,并在调用时进行设置。 一旦调用成功,系统将返回一个结构体,其中包含了新创建工艺路线的各个字段信息,比如路线号、版本号、状态等。此外,如果在创建工艺路线的过程中发生了错误,系统也会返回相应的错误信息供我们进行处理。 总而言之,BAPI_ROUTING_CREATE是一个非常有用的函数模块,它可以帮助我们通过编程的方式在SAP系统中创建新的工艺路线。使用该函数模块,我们可以实现自动化的工艺路线创建,并且能够灵活地设置各种相关属性。 ### 回答3: BAPI_ROUTING_CREATE是一个SAP系统中可用的功能模块,用于创建工艺路线。工艺路线是描述制造过程的一系列步骤和操作的集合。通过使用BAPI_ROUTING_CREATE,可以在SAP系统中创建新的工艺路线。 使用BAPI_ROUTING_CREATE时,需提供一些必要的参数。首先,需要提供一个唯一的工艺路线编号。其次,需要指定工作中心,即进行操作的地点或设备。还需要提供一个有效日期,表示工艺路线的生效日期。此外,还需要指定产品和版本信息。 一旦提供了上述参数,就可以调用BAPI_ROUTING_CREATE来创建工艺路线。系统会根据提供的参数,在数据库中创建一个新的工艺路线记录。可以在工艺路线中添加各种操作和步骤,包括工序、检查点和质量控制点等。还可以定义生产时间、工时和相关的工作中心和资源。 使用BAPI_ROUTING_CREATE时,还可以设置一些其他的可选参数,如是否计划外的操作、成本、工作中心之间的依赖关系等。 总之,BAPI_ROUTING_CREATE是一个方便的功能模块,可以在SAP系统中快速创建新的工艺路线。它提供了许多参数选项,以满足各种需求。通过使用BAPI_ROUTING_CREATE,可以简化和优化制造过程中的工艺路线管理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值