Example #1
0
int connect_v4_prog(struct bpf_sock_addr *ctx)
{
	struct sockaddr_in sa;

	/* Rewrite destination. */
	ctx->user_ip4 = bpf_htonl(DST_REWRITE_IP4);
	ctx->user_port = bpf_htons(DST_REWRITE_PORT4);

	if (ctx->type == SOCK_DGRAM || ctx->type == SOCK_STREAM) {
		///* Rewrite source. */
		memset(&sa, 0, sizeof(sa));

		sa.sin_family = AF_INET;
		sa.sin_port = bpf_htons(0);
		sa.sin_addr.s_addr = bpf_htonl(SRC_REWRITE_IP4);

		if (bpf_bind(ctx, (struct sockaddr *)&sa, sizeof(sa)) != 0)
			return 0;
	}

	return 1;
}
static int handle_rx(void *skb, struct metadata *md) {
  struct __sk_buff *skb2 = (struct __sk_buff *)skb;
  void *data = (void *)(long)skb2->data;
  void *data_end = (void *)(long)skb2->data_end;
  struct eth_hdr *eth = data;
  if (data + sizeof(*eth) > data_end)
    return RX_DROP;
  u32 in_ifc = md->in_ifc;
  #ifdef BPF_TRACE
    bpf_trace_printk("[switch-%d]: in_ifc=%d\n", md->module_id, in_ifc);
  #endif
  // port security on source mac
  #ifdef MAC_SECURITY_INGRESS
  __be64 *mac_lookup = securitymac.lookup(&in_ifc);
  if (mac_lookup)
    if (eth->src != *mac_lookup) {
      #ifdef BPF_TRACE
        bpf_trace_printk("[switch-%d]: mac INGRESS %lx mismatch %lx -> DROP\n",
          md->module_id, PRINT_MAC(eth->src), PRINT_MAC(*mac_lookup));
      #endif
      return RX_DROP;
    }
  #endif
  // port security on source ip
  #ifdef IP_SECURITY_INGRESS
  if (eth->proto == bpf_htons(ETH_P_IP)) {
    __be32 *ip_lookup = securityip.lookup(&in_ifc);
    if (ip_lookup) {
      struct ip_t *ip = data + sizeof(*eth);
      if (data + sizeof(*eth) + sizeof(*ip) > data_end)
        return RX_DROP;
      if (ip->src != *ip_lookup) {
        #ifdef BPF_TRACE
          bpf_trace_printk("[switch-%d]: IP INGRESS %x mismatch %x -> DROP\n",
            md->module_id, bpf_htonl(ip->src), bpf_htonl(*ip_lookup));
        #endif
        return RX_DROP;
      }
    }
  }
  #endif
  #ifdef BPF_TRACE
    bpf_trace_printk("[switch-%d]: mac src:%lx dst:%lx\n",
      md->module_id, PRINT_MAC(eth->src), PRINT_MAC(eth->dst));
  #endif
  //LEARNING PHASE: mapping in_ifc with src_interface
  __be64 src_key = eth->src;
  //lookup in fwdtable. if no key present initialize with interface
  u32 *interface_lookup = fwdtable.lookup_or_init(&src_key, &in_ifc);
  //if the same mac has changed interface, update it
  if (*interface_lookup != in_ifc)
    *interface_lookup = in_ifc;
  //FORWARDING PHASE: select interface(s) to send the packet
  __be64 dst_mac = eth->dst;
  //lookup in forwarding table fwdtable
  u32 *dst_interface = fwdtable.lookup(&dst_mac);
  if (dst_interface) {
    //HIT in forwarding table
    //redirect packet to dst_interface
    #ifdef MAC_SECURITY_EGRESS
    u32 out_iface = *dst_interface;
    __be64 *mac_lookup = securitymac.lookup(&out_iface);
    if (mac_lookup)
      if (eth->dst != *mac_lookup){
        #ifdef BPF_TRACE
          bpf_trace_printk("[switch-%d]: mac EGRESS %lx mismatch %lx -> DROP\n",
            md->module_id, PRINT_MAC(eth->dst), PRINT_MAC(*mac_lookup));
        #endif
        return RX_DROP;
      }
    #endif
    /* do not send packet back on the ingress interface */
    if (*dst_interface == in_ifc)
      return RX_DROP;
    pkt_redirect(skb, md, *dst_interface);
    #ifdef BPF_TRACE
      bpf_trace_printk("[switch-%d]: redirect out_ifc=%d\n", md->module_id, *dst_interface);
    #endif
    return RX_REDIRECT;
  } else {
    #ifdef BPF_TRACE
      bpf_trace_printk("[switch-%d]: Broadcast\n", md->module_id);
    #endif
    pkt_controller(skb, md, PKT_BROADCAST);
    return RX_CONTROLLER;
  }
}