Skip to content

Commit

Permalink
Add support for combined recipe and linux networking v3
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 committed Apr 2, 2024
1 parent 5d1d6b3 commit 94a7dc8
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 @@ -624,8 +624,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 @@ -3140,13 +3140,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 @@ -3172,7 +3176,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 @@ -3242,6 +3277,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 @@ -3263,6 +3299,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 94a7dc8

Please sign in to comment.