Skip to content

Commit

Permalink
lls: generalize handling of ICMPv6 packets
Browse files Browse the repository at this point in the history
  • Loading branch information
cjdoucette committed Oct 30, 2020
1 parent b886027 commit e3d3295
Show file tree
Hide file tree
Showing 7 changed files with 247 additions and 458 deletions.
3 changes: 2 additions & 1 deletion cps/kni.c
Original file line number Diff line number Diff line change
Expand Up @@ -2155,7 +2155,8 @@ kni_process_nd(struct cps_config *cps_conf, struct gatekeeper_if *iface,

icmpv6_hdr = rte_pktmbuf_mtod_offset(buf, struct icmpv6_hdr *,
sizeof(*eth_hdr) + sizeof(struct rte_ipv6_hdr));
if (icmpv6_hdr->type == ND_NEIGHBOR_ADVERTISEMENT) {
if (icmpv6_hdr->type == ND_NEIGHBOR_ADVERTISEMENT_TYPE &&
icmpv6_hdr->code == ND_NEIGHBOR_ADVERTISEMENT_CODE) {
CPS_LOG(NOTICE, "ND Advertisement packet received from KNI attached to %s iface\n",
iface->name);
goto out;
Expand Down
15 changes: 7 additions & 8 deletions cps/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,8 @@ send_nd_reply_kni(struct cps_config *cps_conf, struct cps_nd_req *nd)

/* Set-up ICMPv6 header. */
icmpv6_hdr = (struct icmpv6_hdr *)&ipv6_hdr[1];
icmpv6_hdr->type = ND_NEIGHBOR_ADVERTISEMENT;
icmpv6_hdr->code = 0;
icmpv6_hdr->type = ND_NEIGHBOR_ADVERTISEMENT_TYPE;
icmpv6_hdr->code = ND_NEIGHBOR_ADVERTISEMENT_CODE;
icmpv6_hdr->cksum = 0; /* Calculated below. */

/* Set up ND Advertisement header with target LL addr option. */
Expand Down Expand Up @@ -375,8 +375,8 @@ process_ingress(struct gatekeeper_if *iface, struct rte_kni *kni,
}

static int
pkt_is_nd(struct gatekeeper_if *iface, struct rte_ether_hdr *eth_hdr,
uint16_t pkt_len)
cps_pkt_is_nd_neighbor(struct gatekeeper_if *iface,
struct rte_ether_hdr *eth_hdr, uint16_t pkt_len)
{
struct rte_ipv6_hdr *ipv6_hdr;
struct icmpv6_hdr *icmpv6_hdr;
Expand All @@ -392,11 +392,10 @@ pkt_is_nd(struct gatekeeper_if *iface, struct rte_ether_hdr *eth_hdr,
/*
* Make sure this is an ND neighbor message and that it was
* sent by us (our global address, link-local address, or
* either of the solicited-node multicast addresses.
* either of the solicited-node multicast addresses).
*/
icmpv6_hdr = (struct icmpv6_hdr *)&ipv6_hdr[1];
return (icmpv6_hdr->type == ND_NEIGHBOR_SOLICITATION ||
icmpv6_hdr->type == ND_NEIGHBOR_ADVERTISEMENT) &&
return pkt_is_nd_neighbor(icmpv6_hdr->type, icmpv6_hdr->code) &&
(ipv6_addrs_equal(ipv6_hdr->src_addr,
iface->ll_ip6_addr.s6_addr) ||
ipv6_addrs_equal(ipv6_hdr->src_addr,
Expand Down Expand Up @@ -432,7 +431,7 @@ process_egress(struct cps_config *cps_conf, struct gatekeeper_if *iface,
break;
case RTE_ETHER_TYPE_IPV6: {
uint16_t pkt_len = rte_pktmbuf_data_len(bufs[i]);
if (pkt_is_nd(iface, eth_hdr, pkt_len)) {
if (cps_pkt_is_nd_neighbor(iface, eth_hdr, pkt_len)) {
/* Intercept ND packet and handle it. */
kni_process_nd(cps_conf, iface,
bufs[i], eth_hdr, pkt_len);
Expand Down
72 changes: 56 additions & 16 deletions include/gatekeeper_lls.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,10 @@ enum lls_req_ty {
LLS_REQ_PUT,
/* Request to handle ARP packets received from another block. */
LLS_REQ_ARP,
/* Request to handle ND packets received from another block. */
LLS_REQ_ND,
/* Request to handle ICMP packets received from another block. */
LLS_REQ_ICMP,
/* Request to handle ICMPv6 ping packets received from another block. */
LLS_REQ_PING6,
/* Request to handle ICMPv6 packets received from another block. */
LLS_REQ_ICMP6,
};

/* Replies that come from the LLS block. */
Expand Down Expand Up @@ -378,17 +376,26 @@ struct nd_opt_lladdr {
#define ICMP_PKT_MIN_LEN(l2_len) (l2_len + sizeof(struct rte_ipv4_hdr) + 8)

/*
* Minimum size of an IPv6 ping packet.
* Minimum size of an ICMPv6 packet.
*
* Note that, according to RFC 4443 section 4.1 and section 4.2,
* both the ICMPv6 Echo request header and Echo reply header require 8 bytes.
* Note that the minimum ICMPv6 header size is the four bytes
* defined in struct icmpv6_hdr (RFC 4443).
*/
#define ICMPV6_PKT_MIN_LEN(l2_len) (l2_len + sizeof(struct rte_ipv6_hdr) + 8)
#define ICMPV6_PKT_MIN_LEN(l2_len) (l2_len + sizeof(struct rte_ipv6_hdr) + \
sizeof(struct icmpv6_hdr))

/* Flags for Neighbor Advertisements. */
#define LLS_ND_NA_SOLICITED 0x40000000
#define LLS_ND_NA_OVERRIDE 0x20000000

/* The IPv6 all nodes multicast address. */
static const struct in6_addr ip6_allnodes_mc_addr = {
.s6_addr = {
0xFF, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
}
};

/*
* ICMP message types.
*/
Expand All @@ -406,21 +413,54 @@ struct nd_opt_lladdr {
#define ICMP_FRAG_REQ_DF_CODE (4)

/*
* Supported IPv6 ping packets via the type and code fields
* in struct icmpv6_hdr.
* ICMPv6 message types.
*/

/* ICMPv6 Echo Request. */
#define ICMPV6_ECHO_REQUEST_TYPE (128)
#define ICMPV6_ECHO_REQUEST_CODE (0)

/* ICMPv6 type and code fields for echo reply messages. */
/* ICMPv6 Echo Reply. */
#define ICMPV6_ECHO_REPLY_TYPE (129)
#define ICMPV6_ECHO_REPLY_CODE (0)

/* Supported IPv6 ND packets via the type field in struct icmpv6_hdr. */
#define ND_ROUTER_SOLICITATION (133)
#define ND_ROUTER_ADVERTISEMENT (134)
#define ND_NEIGHBOR_SOLICITATION (135)
#define ND_NEIGHBOR_ADVERTISEMENT (136)
/* ICMPv6 Packet Too Big. */
#define ICMPV6_PACKET_TOO_BIG_TYPE (2)
#define ICMPV6_PACKET_TOO_BIG_CODE (0)

/* ICMPv6 Neighbor Discovery Router Solicitation. */
#define ND_ROUTER_SOLICITATION_TYPE (133)
#define ND_ROUTER_SOLICITATION_CODE (0)

/* ICMPv6 Neighbor Discovery Router Advertisement. */
#define ND_ROUTER_ADVERTISEMENT_TYPE (134)
#define ND_ROUTER_ADVERTISEMENT_CODE (0)

/* ICMPv6 Neighbor Discovery Neighbor Solicitation. */
#define ND_NEIGHBOR_SOLICITATION_TYPE (135)
#define ND_NEIGHBOR_SOLICITATION_CODE (0)

/* ICMPv6 Neighbor Discovery Neighbor Advertisement. */
#define ND_NEIGHBOR_ADVERTISEMENT_TYPE (136)
#define ND_NEIGHBOR_ADVERTISEMENT_CODE (0)

static inline int
pkt_is_nd_router(uint8_t type, uint8_t code)
{
return (type == ND_ROUTER_SOLICITATION_TYPE &&
code == ND_ROUTER_SOLICITATION_CODE) ||
(type == ND_ROUTER_ADVERTISEMENT_TYPE &&
code == ND_ROUTER_ADVERTISEMENT_CODE);
}

static inline int
pkt_is_nd_neighbor(uint8_t type, uint8_t code)
{
return (type == ND_NEIGHBOR_SOLICITATION_TYPE &&
code == ND_NEIGHBOR_SOLICITATION_CODE) ||
(type == ND_NEIGHBOR_ADVERTISEMENT_TYPE &&
code == ND_NEIGHBOR_ADVERTISEMENT_CODE);
}

static inline int
arp_enabled(struct lls_config *lls_conf)
Expand Down
Loading

0 comments on commit e3d3295

Please sign in to comment.