void ofp_nd6_ns_input(odp_packet_t m, int off, int icmp6len) { struct ofp_ether_header *eth; struct ofp_ip6_hdr *ip6; struct ofp_icmp6_hdr *icmp6; struct ofp_ifnet *ifp; (void)icmp6len; ifp = odp_packet_user_ptr(m); eth = (struct ofp_ether_header *) odp_packet_l2_ptr(m, NULL); ip6 = (struct ofp_ip6_hdr *)odp_packet_l3_ptr(m, NULL); icmp6 = (struct ofp_icmp6_hdr *)((uint8_t *)ip6 + off); if (icmp6->ofp_icmp6_data8[20] == OFP_ND_OPT_SOURCE_LINKADDR && !OFP_IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_src) && !OFP_IN6_IS_ADDR_LINKLOCAL(&ip6->ip6_src)) { ofp_set_route6_params(OFP_ROUTE6_ADD, 0 /*vrf*/, ifp->vlan, ifp->port, ip6->ip6_src.ofp_s6_addr, 128 /*masklen*/, ofp_in6addr_any.ofp_s6_addr, OFP_RTF_HOST); ofp_add_mac6(ifp, &ip6->ip6_src.ofp_s6_addr[0], (uint8_t *)ð->ether_shost); } }
void ofp_nd6_na_input(odp_packet_t m, int off, int icmp6len) { struct ofp_ether_header *eth; struct ofp_ip6_hdr *ip6; struct ofp_icmp6_hdr *icmp6; struct ofp_ifnet *ifp; (void)icmp6len; ifp = odp_packet_user_ptr(m); eth = (struct ofp_ether_header *) odp_packet_l2_ptr(m, NULL); ip6 = (struct ofp_ip6_hdr *)odp_packet_l3_ptr(m, NULL); icmp6 = (struct ofp_icmp6_hdr *)((uint8_t *)ip6 + off); if (icmp6->ofp_icmp6_data8[20] == OFP_ND_OPT_TARGET_LINKADDR) { ofp_set_route6_params(OFP_ROUTE6_ADD, 0 /*vrf*/, ifp->vlan, ifp->port, &icmp6->ofp_icmp6_data8[4], 128 /*masklen*/, ofp_in6addr_any.ofp_s6_addr, OFP_RTF_HOST); ofp_add_mac6(ifp, &icmp6->ofp_icmp6_data8[4], (uint8_t *)ð->ether_shost); } }
void f_route_del_v6(struct cli_conn *conn, const char *s) { uint8_t dst6[16]; uint8_t gw6[16]; int mlen; const char *tk; const char *tk_end; const char *last; last = s + strlen(s); /* get IP6NET address*/ tk = s; tk_end = strstr(tk, "/"); if (!tk_end) { ofp_sendf(conn->fd, "Invalid IP6NET\r\n"); sendcrlf(conn); return; } if (!ip6addr_get(tk, tk_end - tk, dst6)) { ofp_sendf(conn->fd, "Invalid IP6NET\r\n"); sendcrlf(conn); return; } /* get IP6NET prefix len*/ tk = tk_end + 1; if (tk >= last) { ofp_sendf(conn->fd, "Invalid IP6NET\r\n"); sendcrlf(conn); return; } tk_end = last; if (tk == tk_end) { ofp_sendf(conn->fd, "Invalid IP6NET\r\n"); sendcrlf(conn); return; } mlen = atoi(tk); ofp_set_route6_params(OFP_ROUTE6_DEL, 0 /*vrf*/, 0 /*vlan*/, 0 /*port*/, dst6, mlen, gw6); sendcrlf(conn); }
void f_route_add_v6(struct cli_conn *conn, const char *s) { uint8_t dst6[16]; uint8_t gw6[16]; int port, vlan, mlen; const char *tk; const char *tk_end; const char *last; last = s + strlen(s); /* get IP6NET address*/ tk = s; tk_end = strstr(tk, "/"); if (!tk_end) { ofp_sendf(conn->fd, "Invalid IP6NET\r\n"); sendcrlf(conn); return; } if (!ip6addr_get(tk, tk_end - tk, dst6)) { ofp_sendf(conn->fd, "Invalid IP6NET\r\n"); sendcrlf(conn); return; } /* get IP6NET prefix len*/ tk = tk_end + 1; if (tk >= last) { ofp_sendf(conn->fd, "Invalid IP6NET\r\n"); sendcrlf(conn); return; } tk_end = strstr(tk, " "); if (!tk_end || (tk == tk_end)) { ofp_sendf(conn->fd, "Invalid IP6NET\r\n"); sendcrlf(conn); return; } mlen = atoi(tk); /* get IP6ADDR */ tk = tk_end + 1; if (tk >= last) { ofp_sendf(conn->fd, "Invalid IP6NET\r\n"); sendcrlf(conn); return; } tk_end = strstr(tk, " "); if (tk_end == NULL) { ofp_sendf(conn->fd, "Invalid IP6ADDR\r\n"); sendcrlf(conn); return; } if (!ip6addr_get(tk, tk_end - tk, gw6)) { ofp_sendf(conn->fd, "Invalid IP6NET\r\n"); sendcrlf(conn); return; } /* get DEV */ tk = tk_end + 1; if (tk >= last) { ofp_sendf(conn->fd, "Invalid DEV\r\n"); sendcrlf(conn); return; } tk_end = last; port = ofp_name_to_port_vlan(tk, &vlan); if (port < 0 || port >= ofp_get_num_ports()) { ofp_sendf(conn->fd, "Invalid port!\r\n"); sendcrlf(conn); return; } ofp_set_route6_params(OFP_ROUTE6_ADD, 0 /*vrf*/, vlan, port, dst6, mlen, gw6); sendcrlf(conn); }
static void test_packet_output_ipv6_to_gre(void) { odp_packet_t pkt = ODP_PACKET_INVALID; odp_event_t ev; int res; struct ofp_ether_header *eth; struct ofp_ip6_hdr *ip6, *ip6_orig; struct ofp_ip *ip; struct ofp_greip *greip; (void)tcp_frame; (void)icmp_frame; (void)arp_frame; (void)icmp6_frame; if (create_odp_packet_ip6(&pkt, ip6udp_frame, sizeof(ip6udp_frame))) { CU_FAIL("Fail to create packet"); return; } ip6 = odp_packet_l3_ptr(pkt, NULL); ofp_set_route6_params(OFP_ROUTE6_ADD, 0 /*vrf*/, 100 /*vlan*/, GRE_PORTS, ip6->ip6_dst.__u6_addr.__u6_addr8, 64 /*masklen*/, 0 /*gw*/, OFP_RTF_NET /* flags */); res = ofp_ip6_output(pkt, NULL); CU_ASSERT_EQUAL(res, OFP_PKT_PROCESSED); res = ofp_send_pending_pkt(); CU_ASSERT_EQUAL(res, OFP_PKT_PROCESSED); ev = odp_queue_deq(dev->outq_def); CU_ASSERT_NOT_EQUAL_FATAL(ev, ODP_EVENT_INVALID); pkt = odp_packet_from_event(ev); CU_ASSERT_EQUAL_FATAL(odp_packet_len(pkt), sizeof(ip6udp_frame) + 20 + 4); eth = odp_packet_l2_ptr(pkt, NULL); if (memcmp(eth->ether_dhost, tun_rem_mac, OFP_ETHER_ADDR_LEN)) CU_FAIL("Bad destination mac address."); if (memcmp(eth->ether_shost, dev->mac, OFP_ETHER_ADDR_LEN)) CU_FAIL("Bad source mac address."); ip = odp_packet_l3_ptr(pkt, NULL); CU_ASSERT_EQUAL(ip->ip_src.s_addr, dev_ip); CU_ASSERT_EQUAL(ip->ip_dst.s_addr, tun_rem_ip); CU_ASSERT_EQUAL(ip->ip_p, OFP_IPPROTO_GRE); greip = (struct ofp_greip *)ip; CU_ASSERT_EQUAL(greip->gi_g.flags, 0); CU_ASSERT_EQUAL(greip->gi_g.ptype, odp_cpu_to_be_16(OFP_ETHERTYPE_IPV6)); /* inner ip */ ip6 = (struct ofp_ip6_hdr *)(greip + 1); ip6_orig = (struct ofp_ip6_hdr *) (&orig_pkt_data[OFP_ETHER_HDR_LEN]); if (memcmp(ip6, ip6_orig, odp_be_to_cpu_16(ip6_orig->ofp_ip6_plen) + sizeof(*ip6))) CU_FAIL("Inner IP packet error."); }