thom311 / libnl

Netlink Library Suite
GNU Lesser General Public License v2.1
419 stars 311 forks source link

need help with rtnl_route_add without gateway but a subnet #364

Closed calvin2021y closed 10 months ago

calvin2021y commented 10 months ago

I want to add this route into table:

10.0.0.0/26 dev eth101 proto kernel scope link src 10.0.0.1

subnet=10.0.0.0/26, ip=10.0.0.1

with code:

        errn0 = nl_addr_parse(subnet, family, &dst_addr);
        if( dst_addr == NULL ) {
            break;
        }
        // nl_addr_set_prefixlen(dst_addr, 24);
        errn0   = rtnl_route_set_dst(route, dst_addr);
        if( errn0 < 0 ) {
            break;
        }

        errn0 = nl_addr_parse(ip, family, &src_addr);
        if( src_addr == NULL ) {
            break;
        }
        errn0   = rtnl_route_set_pref_src(route, src_addr);
        if( errn0 < 0 ) {
            break;
        }

        struct rtnl_nexthop *nh = rtnl_route_nh_alloc();
        if( nh == NULL ) {
            break;
        }
        errn0 = rtnl_route_nh_set_newdst(nh, dst_addr);
        if( errn0 < 0 ) {
            break;
        }
        rtnl_route_nh_set_ifindex(nh, ifindex);
        rtnl_route_add_nexthop(route, nh);

        errn0   = rtnl_route_set_family(route, family);
        if( errn0 < 0 ) {
            break;
        }
        rtnl_route_set_priority(route, RTN_UNSPEC);
        rtnl_route_set_protocol(route, RTPROT_KERNEL);
        rtnl_route_set_scope(route, RT_SCOPE_LINK);
        rtnl_route_set_table(route, RT_TABLE_MAIN);
        // rtnl_route_set_iif(route, ifindex);
        errn0   = rtnl_route_add(sock, route, NLM_F_CREATE | NLM_F_REPLACE);
        if( errn0 < 0 ) {
            break;
        }

get error: "Unspecific failure"

change to:

        errn0 = nl_addr_parse(subnet, family, &dst_addr);
        if( dst_addr == NULL ) {
            break;
        }
        errn0   = rtnl_route_set_dst(route, dst_addr);
        if( errn0 < 0 ) {
            break;
        }

        errn0 = nl_addr_parse(ip, family, &src_addr);
        if( src_addr == NULL ) {
            break;
        }
        errn0   = rtnl_route_set_pref_src(route, src_addr);
        if( errn0 < 0 ) {
            break;
        }
        errn0   = rtnl_route_set_family(route, family);
        if( errn0 < 0 ) {
            break;
        }
        rtnl_route_set_priority(route, RTN_UNSPEC);
        rtnl_route_set_protocol(route, RTPROT_KERNEL);
        rtnl_route_set_scope(route, RT_SCOPE_LINK);
        rtnl_route_set_table(route, RT_TABLE_MAIN);
        rtnl_route_set_iif(route, ifindex);
        errn0   = rtnl_route_add(sock, route, NLM_F_CREATE | NLM_F_REPLACE);
        if( errn0 < 0 ) {
            break;
        }
        line    = 0;

get error: No such device

change to:

        errn0 = nl_addr_parse(subnet, family, &dst_addr);
        if( dst_addr == NULL ) {
            break;
        }
        errn0   = rtnl_route_set_dst(route, dst_addr);
        if( errn0 < 0 ) {
            break;
        }

        errn0 = nl_addr_parse(ip, family, &src_addr);
        if( src_addr == NULL ) {
            break;
        }
        errn0   = rtnl_route_set_src(route, src_addr);
        if( errn0 < 0 ) {
            break;
        }
        errn0   = rtnl_route_set_family(route, family);
        if( errn0 < 0 ) {
            break;
        }
        rtnl_route_set_priority(route, RTN_UNSPEC);
        rtnl_route_set_protocol(route, RTPROT_KERNEL);
        rtnl_route_set_scope(route, RT_SCOPE_LINK);
        rtnl_route_set_table(route, RT_TABLE_MAIN);
        rtnl_route_set_iif(route, ifindex);
        errn0   = rtnl_route_add(sock, route, NLM_F_CREATE | NLM_F_REPLACE);
        if( errn0 < 0 ) {
            break;
        }
        line    = 0;

get error: Source based routing not supported

I find example like this: https://android.googlesource.com/platform/external/libnl/+/kitkat-wear/src/f_route.c, but rtnl_route_set_oif is not exists in 3.8.0 anymore.

calvin2021y commented 10 months ago

try with:

./nl-route-add --scope=link --protocol=kernel --dst=10.0.0.0/24 --nexthop=dev=eth101,via=10.0.0.1
Error: Unable to add route: Unspecific failure

 ./nl-route-add --scope=link --protocol=kernel --dst=10.0.0.0/24 --src=10.0.0.3  --nexthop=dev=eth101,via=10.0.0.1
Error: Unable to set source address: Source based routing not supported

./nl-route-add --iif=eth101 --scope=link --protocol=kernel --dst=10.0.0.0/24 --src=10.0.0.3
Error: Unable to set source address: Source based routing not supported

change --src into --pref-src get Unspecific failure

calvin2021y commented 10 months ago

rtnl_route_add return error No such device, but the route is add into system.

calvin2021y commented 10 months ago

I adjust some order and it get fixed.

        errn0 = nl_addr_parse(subnet, family, &dst_addr);
        if( dst_addr == NULL ) {
            break;
        }
        errn0   = rtnl_route_set_dst(route, dst_addr);
        if( errn0 < 0 ) {
            break;
        }

        errn0 = nl_addr_parse(ip, family, &src_addr);
        if( src_addr == NULL ) {
            break;
        }
        errn0   = rtnl_route_set_family(route, family);
        if( errn0 < 0 ) {
            break;
        }
        errn0   = rtnl_route_set_pref_src(route, src_addr);
        if( errn0 < 0 ) {
            break;
        }
        struct rtnl_nexthop *nh = rtnl_route_nh_alloc();
        if( nh == NULL ) {
            break;
        }
        errn0 = rtnl_route_nh_set_newdst(nh, dst_addr);
        if( errn0 < 0 ) {
            break;
        }
        rtnl_route_nh_set_ifindex(nh, ifindex);
        rtnl_route_add_nexthop(route, nh);
        errn0   = rtnl_route_set_family(route, family);
        if( errn0 < 0 ) {
            break;
        }
        rtnl_route_set_priority(route, RTN_UNSPEC);
        rtnl_route_set_protocol(route, RTPROT_KERNEL);
        rtnl_route_set_scope(route, RT_SCOPE_LINK);
        rtnl_route_set_table(route, RT_TABLE_MAIN);
        rtnl_route_set_iif(route, ifindex);
        errn0   = rtnl_route_add(sock, route, NLM_F_CREATE | NLM_F_REPLACE);
        if( errn0 < 0 ) {
            break;
        }
        line    = 0;