/* * INIT */ static void init_ifnet(void) { char str[256]; ofp_config_interface_up_v4(port, vlan, vrf, dev_ip, 24); /* port 0 */ dev = ofp_get_ifnet(port, vlan); memcpy(dev->mac, dev_mac, OFP_ETHER_ADDR_LEN); dev->if_mtu = def_mtu; #ifdef SP dev->linux_index = port + 3; /* an if index of Linux != port val */ ofp_update_ifindex_lookup_tab(dev); #endif /* SP */ dev->pkt_pool = odp_pool_lookup(pool_name); sprintf(str, "out default queue:%d", port); dev->outq_def = odp_queue_create(str, NULL); if (dev->outq_def == ODP_QUEUE_INVALID) { fail_with_odp("Out default queue create failed.\n"); return; } dev->out_queue_num = 1; dev->out_queue_type = OFP_OUT_QUEUE_TYPE_QUEUE; /* port 0 vlan 1 */ ofp_config_interface_up_v4(port, vlan + 1, vrf, dev_ip + 1, 24); dev_vlan = ofp_get_ifnet(port, vlan + 1); memcpy(dev_vlan->mac, dev_vlan_mac, OFP_ETHER_ADDR_LEN); dev_vlan->if_mtu = def_mtu; #ifdef SP dev_vlan->linux_index = port + 4; /* an if index of Linux != port val */ ofp_update_ifindex_lookup_tab(dev_vlan); #endif /* SP */ dev_vlan->pkt_pool = odp_pool_lookup(pool_name); sprintf(str, "out default queue:%d", port); dev_vlan->outq_def = odp_queue_create(str, NULL); if (dev_vlan->outq_def == ODP_QUEUE_INVALID) { fail_with_odp("Out default queue create failed.\n"); return; } /* Tunnels */ ofp_config_interface_up_tun(GRE_PORTS, 100, 0, dev_ip, tun_rem_ip, tun_p2p, tun_addr, tun_mask); /* No nexthop for tunnel remote address */ ofp_config_interface_up_tun(GRE_PORTS, 200, 0, dev_ip, 0x08070605, tun_p2p + 1, tun_addr + 1, tun_mask); }
static void test_gre_port(void) { int port = 0; uint16_t vlan = 10; uint16_t vrf = 1; uint32_t ifaddr = 0x650AA8C0; /* C0.A8.0A.65 = 192.168.10.101 */ int masklen = 24, gre_ml = 32; uint16_t greid = 100; uint32_t greaddr = 0x010A0A0A; uint32_t grep2p = 0x020A0A0A; struct ofp_ifnet *dev; struct ofp_nh_entry *nh; const char *res; res = ofp_config_interface_up_v4(port, vlan, vrf, ifaddr, masklen); CU_ASSERT_PTR_NULL_FATAL(res); /* Non-existent endpoint in vrf */ res = ofp_config_interface_up_tun(GRE_PORTS, greid, vrf + 1, ifaddr, ifaddr + 1, greaddr, grep2p, gre_ml); CU_ASSERT_PTR_NOT_NULL_FATAL(res); dev = ofp_get_ifnet(GRE_PORTS, greid); CU_ASSERT_PTR_NULL_FATAL(dev); /* Successful test */ res = ofp_config_interface_up_tun(GRE_PORTS, greid, vrf, ifaddr, ifaddr + 1, grep2p, greaddr, gre_ml); CU_ASSERT_PTR_NULL_FATAL(res); dev = ofp_get_ifnet(GRE_PORTS, greid); CU_ASSERT_PTR_NOT_NULL_FATAL(dev); CU_ASSERT_EQUAL(dev->ip_local, ifaddr); CU_ASSERT_EQUAL(dev->ip_remote, ifaddr + 1); CU_ASSERT_EQUAL(dev->ip_addr, greaddr); CU_ASSERT_EQUAL(dev->ip_p2p, grep2p); CU_ASSERT_EQUAL(dev->masklen, gre_ml); CU_ASSERT_EQUAL(dev->if_mtu, ifmtu - 24); nh = ofp_get_next_hop(vrf, grep2p, NULL); assert_next_hop(nh, 0, GRE_PORTS, greid); res = ofp_config_interface_down(port, vlan); CU_ASSERT_PTR_NULL_FATAL(res); res = ofp_config_interface_down(GRE_PORTS, greid); CU_ASSERT_PTR_NULL_FATAL(res); dev = ofp_get_ifnet(GRE_PORTS, greid); CU_ASSERT_PTR_NULL_FATAL(dev); }
/* "ifconfig tunnel gre DEV local IP4ADDR remote IP4ADDR peer IP4ADDR IP4ADDR vrf NUMBER";*/ void f_ifconfig_tun(struct cli_conn *conn, const char *s) { char dev[16], loc[16], rem[16], ip[16], peer[16]; uint32_t tun_loc, tun_rem, addr, p2p; int port, vlan, vrf = 0, masklen = 32; const char *err; if (sscanf(s, "%s %s %s %s %s %d", dev, loc, rem, peer, ip, &vrf) < 5) return; port = ofp_name_to_port_vlan(dev, &vlan); if (port != GRE_PORTS) { ofp_sendf(conn->fd, "Invalid device name.\r\n"); sendcrlf(conn); return; } if (!ip4addr_get(loc, &tun_loc)) return; if (!ip4addr_get(rem, &tun_rem)) return; if (!ip4addr_get(peer, &p2p)) return; if (!ip4addr_get(ip, &addr)) return; err = ofp_config_interface_up_tun(port, vlan, vrf, tun_loc, tun_rem, p2p, addr, masklen); if (err != NULL) ofp_sendf(conn->fd, err); sendcrlf(conn); }
/* * INIT */ static void test_init_ifnet(void) { char str[256]; ofp_config_interface_up_v4(port, vlan, vrf, local_ip, 24); ifnet = ofp_get_ifnet(port, vlan); ifnet->pkt_pool = odp_pool_lookup("packet_pool"); #ifdef SP ifnet->linux_index = port + 3; /* an if index of Linux != port val */ ofp_update_ifindex_lookup_tab(ifnet); sprintf(str, "slow path stack port:%d", port); ifnet->spq_def = odp_queue_create(str, ODP_QUEUE_TYPE_POLL, NULL); if (ifnet->spq_def == ODP_QUEUE_INVALID) { fail_with_odp("Slow path queue create failed.\n"); return; } #endif sprintf(str, "out default queue:%d", port); ifnet->outq_def = odp_queue_create(str, ODP_QUEUE_TYPE_POLL, NULL); if (ifnet->outq_def == ODP_QUEUE_INVALID) { fail_with_odp("Out default queue create failed.\n"); return; } sprintf(str, "interface queue:%d", port); interface_queue[port] = odp_queue_create(str, ODP_QUEUE_TYPE_POLL, NULL); if (interface_queue[port] == ODP_QUEUE_INVALID) { OFP_ERR("Poll queue create failed.\n"); return; } ofp_queue_context_set(interface_queue[port], ifnet); ofp_config_interface_up_tun(GRE_PORTS, 100 + port, vrf, local_ip, tun_rem_ip, tun_p2p, tun_addr, tun_mask); }
int ofp_ioctl(int sockfd, int request, ...) { va_list ap; void *data; struct ofp_ifnet *iface = NULL; struct socket *so = ofp_get_sock_by_fd(sockfd); if (!so) { ofp_errno = OFP_EBADF; return -1; } va_start(ap, request); data = va_arg(ap, void *); va_end(ap); if (request == (int)(OFP_SIOCGIFCONF)) { ofp_errno = ((*so->so_proto->pr_usrreqs->pru_control) (so, request, data, NULL, NULL)); } else if (OFP_IOCGROUP(request) == 'i') { /* All the interface requests start with interface name */ int port, vlan = 0; char *name = data; if (get_port_vlan_by_name(name, &port, &vlan) < 0) { ofp_errno = OFP_EBADF; return -1; } if (request == (int)(OFP_SIOCSIFTUN)) { struct ofp_in_tunreq *treq = data; const char *retstr = ofp_config_interface_up_tun (port, vlan, treq->iftun_vrf, treq->iftun_local_addr.sin_addr.s_addr, treq->iftun_remote_addr.sin_addr.s_addr, treq->iftun_p2p_addr.sin_addr.s_addr, treq->iftun_addr.sin_addr.s_addr, 30); if (!retstr) ofp_errno = 0; else ofp_errno = OFP_EBADMSG; } else { iface = ofp_get_ifnet(port, vlan); if (so->so_proto->pr_usrreqs->pru_control) ofp_errno = ((*so->so_proto->pr_usrreqs->pru_control) (so, request, data, iface, NULL)); else ofp_errno = OFP_EOPNOTSUPP; } } else if (OFP_IOCGROUP(request) == 'r') { int port = 0, vlan = 0; struct ofp_rtentry *rt = data; uint32_t dst = ((struct ofp_sockaddr_in *)&rt->rt_dst)->sin_addr.s_addr; uint32_t mask = ((struct ofp_sockaddr_in *)&rt->rt_genmask)->sin_addr.s_addr; uint32_t gw = ((struct ofp_sockaddr_in *)&rt->rt_gateway)->sin_addr.s_addr; uint32_t maskcpu = odp_be_to_cpu_32(mask); uint32_t mlen = 0; if (request != (int)OFP_SIOCADDRT && request != (int)OFP_SIOCDELRT) { ofp_errno = OFP_EBADF; return -1; } if (request == (int)OFP_SIOCADDRT) { if (rt->rt_dev) { if (get_port_vlan_by_name(rt->rt_dev, &port, &vlan) < 0) { ofp_errno = OFP_EBADF; return -1; } } else { uint32_t flags; struct ofp_nh_entry *nh = ofp_get_next_hop(rt->rt_vrf, gw, &flags); if (!nh) { ofp_errno = OFP_EBADF; return -1; } port = nh->port; vlan = nh->vlan; } } while (maskcpu) { mlen++; maskcpu <<= 1; } ofp_set_route_params((request == (int) OFP_SIOCADDRT) ? OFP_ROUTE_ADD : OFP_ROUTE_DEL, rt->rt_vrf, vlan, port, dst, mlen, gw, (request == (int) OFP_SIOCADDRT) ? (gw ? OFP_RTF_GATEWAY : OFP_RTF_NET) : 0); } else { ofp_errno = ofp_soo_ioctl(so, request, data, NULL, NULL); } if (ofp_errno) return -1; return 0; }