From: Pravin B Shelar <pbshe...@fb.com> Please explain how this patch actually works... creation of the control header makes sense, but I don't understand how sending of a control header is actually triggered.
Signed-off-by: Jonas Bonn <jo...@norrbonn.se> --- drivers/net/gtp.c | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c index 668ed8a4836e..bbce2671de2d 100644 --- a/drivers/net/gtp.c +++ b/drivers/net/gtp.c @@ -683,6 +683,38 @@ static void gtp_push_header(struct sk_buff *skb, struct pdp_ctx *pctx, } } +static inline int gtp1_push_control_header(struct sk_buff *skb, + struct pdp_ctx *pctx, + struct gtpu_metadata *opts, + struct net_device *dev) +{ + struct gtp1_header *gtp1c; + int payload_len; + + if (opts->ver != GTP_METADATA_V1) + return -ENOENT; + + if (opts->type == 0xFE) { + /* for end marker ignore skb data. */ + netdev_dbg(dev, "xmit pkt with null data"); + pskb_trim(skb, 0); + } + if (skb_cow_head(skb, sizeof(*gtp1c)) < 0) + return -ENOMEM; + + payload_len = skb->len; + + gtp1c = skb_push(skb, sizeof(*gtp1c)); + + gtp1c->flags = opts->flags; + gtp1c->type = opts->type; + gtp1c->length = htons(payload_len); + gtp1c->tid = htonl(pctx->u.v1.o_tei); + netdev_dbg(dev, "xmit control pkt: ver %d flags %x type %x pkt len %d tid %x", + opts->ver, opts->flags, opts->type, skb->len, pctx->u.v1.o_tei); + return 0; +} + static int gtp_xmit_ip4(struct sk_buff *skb, struct net_device *dev) { struct gtp_dev *gtp = netdev_priv(dev); @@ -807,7 +839,16 @@ static int gtp_xmit_ip4(struct sk_buff *skb, struct net_device *dev) skb_set_inner_protocol(skb, skb->protocol); - gtp_push_header(skb, pctx, &port); + if (unlikely(opts)) { + port = htons(GTP1U_PORT); + r = gtp1_push_control_header(skb, pctx, opts, dev); + if (r) { + netdev_info(dev, "cntr pkt error %d", r); + goto err_rt; + } + } else { + gtp_push_header(skb, pctx, &port); + } iph = ip_hdr(skb); netdev_dbg(dev, "gtp -> IP src: %pI4 dst: %pI4\n", -- 2.27.0