static bool add_encap(struct rtattr *rta, size_t len, encap_t *encap) { struct rtattr *nest; nest = rta_nest(rta, len, RTA_ENCAP); switch (encap->type) { case LWTUNNEL_ENCAP_MPLS: add_encap_mpls(rta, len, encap); break; case LWTUNNEL_ENCAP_IP: add_encap_ip(rta, len, encap); break; case LWTUNNEL_ENCAP_ILA: add_encap_ila(rta, len, encap); break; case LWTUNNEL_ENCAP_IP6: add_encap_ip6(rta, len, encap); break; default: log_message(LOG_INFO, "unknown encap type %d", encap->type); break; } rta_nest_end(rta, nest); rta_addattr16(rta, len, RTA_ENCAP_TYPE, encap->type); return true; }
static void add_encap_ip6(struct rtattr *rta, size_t len, const encap_t *encap) { if (encap->flags & IPROUTE_BIT_ENCAP_ID) rta_addattr64(rta, len, LWTUNNEL_IP6_ID, htonll(encap->ip6.id)); if (encap->ip6.dst) rta_addattr_l(rta, len, LWTUNNEL_IP6_DST, &encap->ip6.dst->u.sin6_addr, sizeof(encap->ip6.dst->u.sin6_addr)); if (encap->ip6.src) rta_addattr_l(rta, len, LWTUNNEL_IP6_SRC, &encap->ip6.src->u.sin6_addr, sizeof(encap->ip6.src->u.sin6_addr)); if (encap->flags & IPROUTE_BIT_ENCAP_DSFIELD) rta_addattr8(rta, len, LWTUNNEL_IP6_TC, encap->ip6.tc); if (encap->flags & IPROUTE_BIT_ENCAP_HOPLIMIT) rta_addattr8(rta, len, LWTUNNEL_IP6_HOPLIMIT, encap->ip6.hoplimit); if (encap->flags & IPROUTE_BIT_ENCAP_FLAGS) rta_addattr16(rta, len, LWTUNNEL_IP6_FLAGS, encap->ip6.flags); }
static void add_encap_ip(struct rtattr *rta, size_t len, const encap_t *encap) { if (encap->flags & IPROUTE_BIT_ENCAP_ID) rta_addattr64(rta, len, LWTUNNEL_IP_ID, htonll(encap->ip.id)); if (encap->ip.dst) rta_addattr_l(rta, len, LWTUNNEL_IP_DST, &encap->ip.dst->u.sin.sin_addr.s_addr, sizeof(encap->ip.dst->u.sin.sin_addr.s_addr)); if (encap->ip.src) rta_addattr_l(rta, len, LWTUNNEL_IP_SRC, &encap->ip.src->u.sin.sin_addr.s_addr, sizeof(encap->ip.src->u.sin.sin_addr.s_addr)); if (encap->flags & IPROUTE_BIT_ENCAP_DSFIELD) rta_addattr8(rta, len, LWTUNNEL_IP_TOS, encap->ip.tos); if (encap->flags & IPROUTE_BIT_ENCAP_HOPLIMIT) rta_addattr8(rta, len, LWTUNNEL_IP_TTL, encap->ip.ttl); if (encap->flags & IPROUTE_BIT_ENCAP_FLAGS) rta_addattr16(rta, len, LWTUNNEL_IP_FLAGS, encap->ip.flags); }
int lwt_parse_encap(struct rtattr *rta, size_t len, int *argcp, char ***argvp) { struct rtattr *nest; int argc = *argcp; char **argv = *argvp; __u16 type; NEXT_ARG(); type = read_encap_type(*argv); if (!type) invarg("\"encap type\" value is invalid\n", *argv); NEXT_ARG(); if (argc <= 1) { fprintf(stderr, "Error: unexpected end of line after \"encap\"\n"); exit(-1); } nest = rta_nest(rta, 1024, RTA_ENCAP); switch (type) { case LWTUNNEL_ENCAP_MPLS: parse_encap_mpls(rta, len, &argc, &argv); break; case LWTUNNEL_ENCAP_IP: parse_encap_ip(rta, len, &argc, &argv); break; case LWTUNNEL_ENCAP_ILA: parse_encap_ila(rta, len, &argc, &argv); break; case LWTUNNEL_ENCAP_IP6: parse_encap_ip6(rta, len, &argc, &argv); break; default: fprintf(stderr, "Error: unsupported encap type\n"); break; } rta_nest_end(rta, nest); rta_addattr16(rta, 1024, RTA_ENCAP_TYPE, type); *argcp = argc; *argvp = argv; return 0; }