Beispiel #1
0
static int handle_v4_route(
        enum monitor_opp opp,
        orc_options_t * options,
        struct nlmsghdr * nl_msg)
{
    int err;
    char buf[BUFLEN];
    char intfnam[IFNAMSIZ];
    l3_next_hop_id_t next_hop;
    u32 netmask;
    orc_v4_route_t entry;

    int success = parse_v4_route(options, nl_msg, &entry);
    if (success == 0)
    {
        orc_trace("Ignoring irrelevant(?) route update\n");
        return 0;
    }
    else if (success == -1)
    {
        orc_warn("Error parsing v4 route update - ignoring\n");
        return -1;
    }

    if (entry.gateway_valid)
        snprintf(buf, BUFLEN, "via gateway "IPV4_FORMAT,
                IPV4_ADDR_PRINT(entry.gateway));
    else
        snprintf(buf, BUFLEN, "direct");
    orc_info("%s IPv4 Route: " IPV4_FORMAT "/%d %s on intf %s (%d)\n",
            ((opp == OP_ADD)? "Adding" : "Deleting"),
            IPV4_ADDR_PRINT(entry.dst_ip),
            entry.dst_mask_len,
            buf,
            interface_index_to_name(entry.dst_if_index, intfnam, IFNAMSIZ),
            entry.dst_if_index);

    netmask = ~((1<<(32-entry.dst_mask_len))-1);
    if (next_hop_lookup( Next_Hop_DB, entry.gateway, &next_hop))
    {
        orc_debug("Found next_hop_id=%d for gateway " IPV4_FORMAT "\n",
                    next_hop, IPV4_ADDR_PRINT(entry.gateway));
    }
    else
        next_hop = NEXT_HOP_KERNEL; /** software forward until we learn
                                     * next_hop via ARP
                                     **/

    if (opp == OP_ADD)
    {

        /* Call the driver to actually add the route IF it has a gateway */
        if (entry.gateway_valid)
        {
            /** even if we know the next hop, register
             * as pending anyway because the next hop could
             * expire and we need to be able to look it up for the lifetime of
             * the route
             */
            if ((err = pending_next_hop_add_gateway(
                    Next_Hop_DB,
                    entry.gateway,
                    entry.dst_ip,
                    netmask)) != 0)
            {
                orc_debug("pending_next_hop_add_gateway() failed: %d\n",
                        err);
            }
            call_add_l3_v4_route(options,
                    entry.dst_ip,
                    netmask,
                    next_hop
                );
        } else {
            if ((err = pending_next_hop_add_direct(
                    Next_Hop_DB,
                    entry.dst_ip,
                    netmask)) != 0)
            {
                orc_debug("pending_next_hop_add_direct() failed: %d\n",
                        err);
            }
        }
    }
    else    /* opp == OP_DEL  */
    {
        if (entry.gateway_valid)
        {
            orc_debug("Calling drv->del_l3_v4_route(" IPV4_FORMAT "/"
                    IPV4_FORMAT",next_hop=%d)\n",
                    IPV4_ADDR_PRINT(entry.dst_ip),
                    IPV4_ADDR_PRINT(netmask),
                    next_hop
                );
            /* call the driver to delete the route */
            options->drv->del_l3_v4_route(
                    entry.dst_ip,
                    netmask,
                    next_hop
                );
            /* delete the pending next_hop */
            if ((err = pending_next_hop_del_gateway(
                    Next_Hop_DB,
                    entry.gateway,
                    entry.dst_ip,
                    netmask)) != 0)
            {
                orc_debug("pending_next_hop_del_gateway() failed: %d\n",
                        err);
            }
        } else {    /* direct route */
            if ((err = pending_next_hop_del_direct(
                    Next_Hop_DB,
                    entry.dst_ip,
                    netmask)) != 0)
            {
                orc_debug("pending_next_hop_del_gateway() failed: %d\n",
                        err);
            }
        }
    }

    return success;
}
Beispiel #2
0
int options_parse( orc_options_t * options, char * argv[], int argc)
{
    int c;
    int opt_index = 0;
    int done = 0;
    while ( !done )
    {
        c = getopt_long(argc, argv, OPT_STRING, long_options, &opt_index);
        switch (c)
        {
        case 'd':
            options->driver = optarg;
            orc_log("Setting driver to \"%s\"\n", options->driver);
            break;
        case 'D':
            if (optarg != NULL)
            {
                int debug = atoi(optarg);
                if (debug >= ORC_LOG_MAX)
                    usage("--debug: value out of range:", optarg);
                options->debug = atoi(optarg);
            }
            else
            {
                options->debug = ORC_LOG_DEBUG;
            }
            DEBUG_THRESHOLD = options->debug;
            orc_log("Setting Debug level to %s\n", orc_log_threshold());

            break;
        case 'M':
            options->daemon = 1;
            break;
        case 'p':
            if (options->num_driver_paths >= MAX_DRIVER_PATHS)
                usage("Too many driver paths specified", NULL);
            options->driver_paths[options->num_driver_paths++] =
                optarg;
            orc_log("Adding to driver search path: \"%s\"\n", optarg);
            break;
        case 'P':
            options->ports_only = 1;
            break;
        case 'V':
            options->verbose = 1;
            break;
        case 'h':
            usage("Help requested", NULL);
            break;
        case 'i':
            if (optarg == NULL)
                usage("option missing interface prefix",NULL);
            options->ifnam_prefix = strdup(optarg);
            orc_info("Setting interface prefix to \"%s\"\n", options->ifnam_prefix);
            break;
        case '?':
            usage("Invalid option", argv[optind]);
            break;
        case -1:
            done = 1;
            break;
        };

    }
    return opt_index + 1;
}