Skip to content

Commit

Permalink
Add support for combined recipe and linux networking v3 (#108)
Browse files Browse the repository at this point in the history
Add support for updating P4 tables for maintaining IP and mac addresses
learnt from a flow with ARP response. This will be used when reconstructing L2
after IPSEC packet is decrypted

Signed-off-by: nupuruttarwar <[email protected]>
  • Loading branch information
nupuruttarwar authored and ffoulkes committed May 29, 2024
1 parent b8728e1 commit fd4829d
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 4 deletions.
11 changes: 11 additions & 0 deletions include/openvswitch/ovs-p4rt.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,21 @@ struct mac_learning_info {
uint8_t mac_addr[6];
uint8_t bridge_id;
uint32_t src_port;
uint32_t rx_src_port;
struct port_vlan_info vlan_info;
union {
struct tunnel_info tnl_info;
struct vlan_info vln_info;
};
};

struct ip_mac_map_info {
uint8_t src_mac_addr[6];
uint8_t dst_mac_addr[6];
struct p4_ipaddr src_ip_addr;
struct p4_ipaddr dst_ip_addr;
};

// Function declarations
extern void ConfigFdbTableEntry(struct mac_learning_info learn_info,
bool insert_entry);
Expand All @@ -106,6 +114,9 @@ extern void ConfigRxTunnelSrcTableEntry(struct tunnel_info tunnel_info,

extern enum ovs_tunnel_type TunnelTypeStrtoEnum(const char* tnl_type);

extern void ConfigIpMacMapTableEntry(struct ip_mac_map_info learn_info,
bool insert_entry);

#ifdef __cplusplus
} // extern "C"
#endif
Expand Down
12 changes: 11 additions & 1 deletion lib/mac-learning.c
Original file line number Diff line number Diff line change
Expand Up @@ -630,8 +630,18 @@ mac_learning_expire(struct mac_learning *ml, struct mac_entry *e)
fdb_info.is_vlan = true;
fdb_info.bridge_id = ml->p4_bridge_id;
ConfigFdbTableEntry(fdb_info, false);

// Remove the corresponding ip_mac tables both for src ip and dst ip
struct ip_mac_map_info ip_info;
memset(&ip_info, 0, sizeof(ip_info));
ip_info.src_ip_addr.family = AF_INET;
ip_info.src_ip_addr.ip.v4addr.s_addr = e->nw_src;
ip_info.dst_ip_addr.family = AF_INET;
ip_info.dst_ip_addr.ip.v4addr.s_addr = e->nw_dst;
// TODO: Update IPv6 fields when IPv6 support is added
ConfigIpMacMapTableEntry(ip_info, false);
}
#endif
#endif // P4OVS
free(e);
}

Expand Down
6 changes: 6 additions & 0 deletions lib/mac-learning.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,12 @@ struct mac_entry {
* The client-specified data is mlport->port. */
struct mac_learning_port *mlport;
struct ovs_list port_lru_node; /* In mac_learning_port's "port_lru"s. */
#if defined(P4OVS)
/* P4 specific fields to maintain corresponding IP's */
ovs_be32 nw_src; /* IPv4 source address or ARP SPA. */
ovs_be32 nw_dst; /* IPv4 destination address or ARP TPA. */
// TODO: Add IPv6 fields when IPv6 support is added
#endif
};

static inline void *mac_entry_get_port(const struct mac_learning *ml,
Expand Down
65 changes: 62 additions & 3 deletions ofproto/ofproto-dpif-xlate.c
Original file line number Diff line number Diff line change
Expand Up @@ -3278,13 +3278,17 @@ get_fdb_data(struct xport *port, struct eth_addr mac_addr,
if (!memcmp(smac.ea, mac_addr.ea, sizeof(smac))) {
VLOG_DBG("Ignore self MAC learn use case for port: %s",
port_name);
return -1;

/* Even for self mac, FDB tables needs to be programmed since Port
* representors are used as underlay ports. Otherwise, underlay port
* traffic will go through slow path which is not advisable
*/
//return -1;
}
/* this SRC port MAC is needed to configure FDB entry
* for its corresponding HOST port or Phy port.
*/
fdb_info->src_port = smac.ea[1] + VSI_ID_OFFSET;
fdb_info->rx_src_port = mac_addr.ea[1] + VSI_ID_OFFSET;
VLOG_DBG("Continue, this is latest LNW");
} else {
fdb_info->is_vlan = true;
Expand All @@ -3310,7 +3314,38 @@ get_fdb_data(struct xport *port, struct eth_addr mac_addr,

return 0;
}
#endif

static inline int32_t
valid_ip_addr(ovs_be32 nw_addr) {
return
(nw_addr && nw_addr != INADDR_ANY &&
nw_addr != INADDR_LOOPBACK && nw_addr != 0xffffffff);
}

static int32_t
update_ip_mac_map_info(const struct flow *flow,
struct ip_mac_map_info *ip_mac_map_info)
{
if (!flow) {
return -1;
}

memcpy(ip_mac_map_info->src_mac_addr, flow->dl_src.ea, sizeof(ip_mac_map_info->src_mac_addr));
memcpy(ip_mac_map_info->dst_mac_addr, flow->dl_dst.ea, sizeof(ip_mac_map_info->dst_mac_addr));

//Program the entiry only for an ARP response where we have valid IP's and MAC for both src and dst
if (valid_ip_addr(flow->nw_src) && !eth_addr_is_broadcast(flow->dl_src) &&
valid_ip_addr(flow->nw_dst) && !eth_addr_is_broadcast(flow->dl_dst)) {
ip_mac_map_info->src_ip_addr.family = AF_INET;
ip_mac_map_info->src_ip_addr.ip.v4addr.s_addr = flow->nw_src;

ip_mac_map_info->dst_ip_addr.family = AF_INET;
ip_mac_map_info->dst_ip_addr.ip.v4addr.s_addr = flow->nw_dst;
}

return -1;
}
#endif // P4OVS

static void
xlate_normal(struct xlate_ctx *ctx)
Expand Down Expand Up @@ -3380,6 +3415,7 @@ xlate_normal(struct xlate_ctx *ctx)
&& flow->packet_type == htonl(PT_ETH)
&& in_port && in_port->pt_mode != NETDEV_PT_LEGACY_L3
) {
//The function below calls mac_learning_insert
update_learning_table(ctx, in_xbundle, flow->dl_src, vlan,
is_grat_arp);
}
Expand All @@ -3401,6 +3437,29 @@ xlate_normal(struct xlate_ctx *ctx)
}
p4ovs_unlock(&p4ovs_fdb_entry_lock);
}

// Update the recently added MAC entry with flow info
struct mac_entry *e;

ovs_rwlock_wrlock(&ctx->xbridge->ml->rwlock);
e = mac_learning_lookup(ctx->xbridge->ml, flow->dl_src, vlan);
if (e) {
e->nw_src = flow->nw_src;
e->nw_dst = flow->nw_dst;
//TODO: Update IPv6 info in MAC entry when IPv6 support is added
}
ovs_rwlock_unlock(&ctx->xbridge->ml->rwlock);

if (ovs_p4_offload_enabled()) {
struct ip_mac_map_info ip_info;
memset(&ip_info, 0, sizeof(ip_info));
if (update_ip_mac_map_info(flow, &ip_info)) {
ConfigIpMacMapTableEntry(ip_info, true);
}
} else {
VLOG_DBG("P4 offload disabled, skipping programming ");
}

#endif

if (ctx->xin->xcache && in_xbundle != &ofpp_none_bundle) {
Expand Down

0 comments on commit fd4829d

Please sign in to comment.