int ovs_tunnel_get_egress_info(struct dp_upcall_info *upcall, struct net *net, struct sk_buff *skb, u8 ipproto, __be16 tp_src, __be16 tp_dst) { struct ip_tunnel_info *egress_tun_info = upcall->egress_tun_info; struct ip_tunnel_info *tun_info = skb_tunnel_info(skb); const struct ip_tunnel_key *tun_key; u32 skb_mark = skb->mark; struct rtable *rt; struct flowi4 fl; if (unlikely(!tun_info)) return -EINVAL; if (ip_tunnel_info_af(tun_info) != AF_INET) return -EINVAL; tun_key = &tun_info->key; /* Route lookup to get srouce IP address. * The process may need to be changed if the corresponding process * in vports ops changed. */ rt = ovs_tunnel_route_lookup(net, tun_key, skb_mark, &fl, ipproto); if (IS_ERR(rt)) return PTR_ERR(rt); ip_rt_put(rt); /* Generate egress_tun_info based on tun_info, * saddr, tp_src and tp_dst */ ip_tunnel_key_init(&egress_tun_info->key, fl.saddr, tun_key->u.ipv4.dst, tun_key->tos, tun_key->ttl, tp_src, tp_dst, tun_key->tun_id, tun_key->tun_flags); egress_tun_info->options_len = tun_info->options_len; egress_tun_info->mode = tun_info->mode; upcall->egress_tun_opts = ip_tunnel_info_opts(tun_info); return 0; }
static inline struct metadata_dst *rpl__ip_tun_set_dst(__be32 saddr, __be32 daddr, __u8 tos, __u8 ttl, __be16 tp_dst, __be16 flags, __be64 tunnel_id, int md_size) { struct metadata_dst *tun_dst; tun_dst = rpl_tun_rx_dst(md_size); if (!tun_dst) return NULL; ip_tunnel_key_init(&tun_dst->u.tun_info.key, saddr, daddr, tos, ttl, 0, 0, tp_dst, tunnel_id, flags); return tun_dst; }