Esempio n. 1
0
static int
route_table_reset(void)
{
    struct nl_dump dump;
    struct rtgenmsg *rtmsg;
    uint64_t reply_stub[NL_DUMP_BUFSIZE / 8];
    struct ofpbuf request, reply, buf;

    route_map_clear();
    route_table_valid = true;
    rt_change_seq++;

    ofpbuf_init(&request, 0);

    nl_msg_put_nlmsghdr(&request, sizeof *rtmsg, RTM_GETROUTE, NLM_F_REQUEST);

    rtmsg = ofpbuf_put_zeros(&request, sizeof *rtmsg);
    rtmsg->rtgen_family = AF_UNSPEC;

    nl_dump_start(&dump, NETLINK_ROUTE, &request);
    ofpbuf_uninit(&request);

    ofpbuf_use_stub(&buf, reply_stub, sizeof reply_stub);
    while (nl_dump_next(&dump, &reply, &buf)) {
        struct route_table_msg msg;

        if (route_table_parse(&reply, &msg)) {
            route_table_handle_msg(&msg);
        }
    }
    ofpbuf_uninit(&buf);

    return nl_dump_done(&dump);
}
Esempio n. 2
0
/* Initialize a conntrack netlink dump. */
int
nl_ct_dump_start(struct nl_ct_dump_state **statep, const uint16_t *zone)
{
    struct nl_ct_dump_state *state;

    *statep = state = xzalloc(sizeof *state);
    ofpbuf_init(&state->buf, NL_DUMP_BUFSIZE);

    if (zone) {
        state->filter_zone = true;
        state->zone = *zone;
    }

    nl_msg_put_nfgenmsg(&state->buf, 0, AF_UNSPEC, NFNL_SUBSYS_CTNETLINK,
                        IPCTNL_MSG_CT_GET, NLM_F_REQUEST);
    nl_dump_start(&state->dump, NETLINK_NETFILTER, &state->buf);
    ofpbuf_clear(&state->buf);

    return 0;
}
Esempio n. 3
0
int
nl_ct_flush_zone(uint16_t flush_zone)
{
    /* Apparently, there's no netlink interface to flush a specific zone.
     * This code dumps every connection, checks the zone and eventually
     * delete the entry.
     *
     * This is race-prone, but it is better than using shell scripts. */

    struct nl_dump dump;
    struct ofpbuf buf, reply, delete;

    ofpbuf_init(&buf, NL_DUMP_BUFSIZE);
    ofpbuf_init(&delete, NL_DUMP_BUFSIZE);

    nl_msg_put_nfgenmsg(&buf, 0, AF_UNSPEC, NFNL_SUBSYS_CTNETLINK,
                        IPCTNL_MSG_CT_GET, NLM_F_REQUEST);
    nl_dump_start(&dump, NETLINK_NETFILTER, &buf);
    ofpbuf_clear(&buf);

    for (;;) {
        struct nlattr *attrs[ARRAY_SIZE(nfnlgrp_conntrack_policy)];
        enum nl_ct_event_type event_type;
        uint8_t nfgen_family;
        uint16_t zone = 0;

        if (!nl_dump_next(&dump, &reply, &buf)) {
            break;
        }

        if (!nl_ct_parse_header_policy(&reply, &event_type, &nfgen_family,
                                       attrs)) {
            continue;
        };

        if (attrs[CTA_ZONE]) {
            zone = ntohs(nl_attr_get_be16(attrs[CTA_ZONE]));
        }

        if (zone != flush_zone) {
            /* The entry is not in the zone we're flushing. */
            continue;
        }
        nl_msg_put_nfgenmsg(&delete, 0, nfgen_family, NFNL_SUBSYS_CTNETLINK,
                            IPCTNL_MSG_CT_DELETE, NLM_F_REQUEST);

        nl_msg_put_be16(&delete, CTA_ZONE, htons(zone));
        nl_msg_put_unspec(&delete, CTA_TUPLE_ORIG, attrs[CTA_TUPLE_ORIG] + 1,
                          attrs[CTA_TUPLE_ORIG]->nla_len - NLA_HDRLEN);
        nl_msg_put_unspec(&delete, CTA_ID, attrs[CTA_ID] + 1,
                          attrs[CTA_ID]->nla_len - NLA_HDRLEN);
        nl_transact(NETLINK_NETFILTER, &delete, NULL);
        ofpbuf_clear(&delete);
    }

    nl_dump_done(&dump);

    ofpbuf_uninit(&delete);
    ofpbuf_uninit(&buf);

    /* Expectations are flushed automatically, because they do not
     * have a master connection anymore */
    return 0;
}