mirror of
https://github.com/openvswitch/ovs
synced 2025-08-31 06:15:47 +00:00
userspace: Add GTP-U support.
GTP, GPRS Tunneling Protocol, is a group of IP-based communications protocols used to carry general packet radio service (GPRS) within GSM, UMTS and LTE networks. GTP protocol has two parts: Signalling (GTP-Control, GTP-C) and User data (GTP-User, GTP-U). GTP-C is used for setting up GTP-U protocol, which is an IP-in-UDP tunneling protocol. Usually GTP is used in connecting between base station for radio, Serving Gateway (S-GW), and PDN Gateway (P-GW). This patch implements GTP-U protocol for userspace datapath, supporting only required header fields and G-PDU message type. See spec in: https://tools.ietf.org/html/draft-hmm-dmm-5g-uplane-analysis-00 Tested-at: https://travis-ci.org/github/williamtu/ovs-travis/builds/666518784 Signed-off-by: Feng Yang <yangfengee04@gmail.com> Co-authored-by: Feng Yang <yangfengee04@gmail.com> Signed-off-by: Yi Yang <yangyi01@inspur.com> Co-authored-by: Yi Yang <yangyi01@inspur.com> Signed-off-by: William Tu <u9012063@gmail.com> Acked-by: Ben Pfaff <blp@ovn.org>
This commit is contained in:
28
lib/flow.c
28
lib/flow.c
@@ -129,7 +129,7 @@ struct mf_ctx {
|
||||
* away. Some GCC versions gave warnings on ALWAYS_INLINE, so these are
|
||||
* defined as macros. */
|
||||
|
||||
#if (FLOW_WC_SEQ != 41)
|
||||
#if (FLOW_WC_SEQ != 42)
|
||||
#define MINIFLOW_ASSERT(X) ovs_assert(X)
|
||||
BUILD_MESSAGE("FLOW_WC_SEQ changed: miniflow_extract() will have runtime "
|
||||
"assertions enabled. Consider updating FLOW_WC_SEQ after "
|
||||
@@ -731,7 +731,7 @@ void
|
||||
miniflow_extract(struct dp_packet *packet, struct miniflow *dst)
|
||||
{
|
||||
/* Add code to this function (or its callees) to extract new fields. */
|
||||
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 41);
|
||||
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 42);
|
||||
|
||||
const struct pkt_metadata *md = &packet->md;
|
||||
const void *data = dp_packet_data(packet);
|
||||
@@ -1187,7 +1187,7 @@ flow_get_metadata(const struct flow *flow, struct match *flow_metadata)
|
||||
{
|
||||
int i;
|
||||
|
||||
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 41);
|
||||
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 42);
|
||||
|
||||
match_init_catchall(flow_metadata);
|
||||
if (flow->tunnel.tun_id != htonll(0)) {
|
||||
@@ -1227,6 +1227,12 @@ flow_get_metadata(const struct flow *flow, struct match *flow_metadata)
|
||||
if (flow->tunnel.erspan_hwid) {
|
||||
match_set_tun_erspan_hwid(flow_metadata, flow->tunnel.erspan_hwid);
|
||||
}
|
||||
if (flow->tunnel.gtpu_flags) {
|
||||
match_set_tun_gtpu_flags(flow_metadata, flow->tunnel.gtpu_flags);
|
||||
}
|
||||
if (flow->tunnel.gtpu_msgtype) {
|
||||
match_set_tun_gtpu_msgtype(flow_metadata, flow->tunnel.gtpu_msgtype);
|
||||
}
|
||||
tun_metadata_get_fmd(&flow->tunnel, flow_metadata);
|
||||
if (flow->metadata != htonll(0)) {
|
||||
match_set_metadata(flow_metadata, flow->metadata);
|
||||
@@ -1767,7 +1773,7 @@ flow_wildcards_init_for_packet(struct flow_wildcards *wc,
|
||||
memset(&wc->masks, 0x0, sizeof wc->masks);
|
||||
|
||||
/* Update this function whenever struct flow changes. */
|
||||
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 41);
|
||||
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 42);
|
||||
|
||||
if (flow_tnl_dst_is_set(&flow->tunnel)) {
|
||||
if (flow->tunnel.flags & FLOW_TNL_F_KEY) {
|
||||
@@ -1788,6 +1794,8 @@ flow_wildcards_init_for_packet(struct flow_wildcards *wc,
|
||||
WC_MASK_FIELD(wc, tunnel.erspan_idx);
|
||||
WC_MASK_FIELD(wc, tunnel.erspan_dir);
|
||||
WC_MASK_FIELD(wc, tunnel.erspan_hwid);
|
||||
WC_MASK_FIELD(wc, tunnel.gtpu_flags);
|
||||
WC_MASK_FIELD(wc, tunnel.gtpu_msgtype);
|
||||
|
||||
if (!(flow->tunnel.flags & FLOW_TNL_F_UDPIF)) {
|
||||
if (flow->tunnel.metadata.present.map) {
|
||||
@@ -1918,7 +1926,7 @@ void
|
||||
flow_wc_map(const struct flow *flow, struct flowmap *map)
|
||||
{
|
||||
/* Update this function whenever struct flow changes. */
|
||||
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 41);
|
||||
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 42);
|
||||
|
||||
flowmap_init(map);
|
||||
|
||||
@@ -2021,7 +2029,7 @@ void
|
||||
flow_wildcards_clear_non_packet_fields(struct flow_wildcards *wc)
|
||||
{
|
||||
/* Update this function whenever struct flow changes. */
|
||||
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 41);
|
||||
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 42);
|
||||
|
||||
memset(&wc->masks.metadata, 0, sizeof wc->masks.metadata);
|
||||
memset(&wc->masks.regs, 0, sizeof wc->masks.regs);
|
||||
@@ -2165,7 +2173,7 @@ flow_wildcards_set_xxreg_mask(struct flow_wildcards *wc, int idx,
|
||||
uint32_t
|
||||
miniflow_hash_5tuple(const struct miniflow *flow, uint32_t basis)
|
||||
{
|
||||
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 41);
|
||||
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 42);
|
||||
uint32_t hash = basis;
|
||||
|
||||
if (flow) {
|
||||
@@ -2212,7 +2220,7 @@ ASSERT_SEQUENTIAL(ipv6_src, ipv6_dst);
|
||||
uint32_t
|
||||
flow_hash_5tuple(const struct flow *flow, uint32_t basis)
|
||||
{
|
||||
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 41);
|
||||
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 42);
|
||||
uint32_t hash = basis;
|
||||
|
||||
if (flow) {
|
||||
@@ -2890,7 +2898,7 @@ flow_push_mpls(struct flow *flow, int n, ovs_be16 mpls_eth_type,
|
||||
|
||||
if (clear_flow_L3) {
|
||||
/* Clear all L3 and L4 fields and dp_hash. */
|
||||
BUILD_ASSERT(FLOW_WC_SEQ == 41);
|
||||
BUILD_ASSERT(FLOW_WC_SEQ == 42);
|
||||
memset((char *) flow + FLOW_SEGMENT_2_ENDS_AT, 0,
|
||||
sizeof(struct flow) - FLOW_SEGMENT_2_ENDS_AT);
|
||||
flow->dp_hash = 0;
|
||||
@@ -3188,7 +3196,7 @@ flow_compose(struct dp_packet *p, const struct flow *flow,
|
||||
/* Add code to this function (or its callees) for emitting new fields or
|
||||
* protocols. (This isn't essential, so it can be skipped for initial
|
||||
* testing.) */
|
||||
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 41);
|
||||
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 42);
|
||||
|
||||
uint32_t pseudo_hdr_csum;
|
||||
size_t l4_len;
|
||||
|
Reference in New Issue
Block a user