Directing Traffic to a Different Routing Table

SDK applications have two options for redirecting traffic to a routing table.

Using libssd to Add a Next-Hop Table Entry

Using libssd, SDK applications can dynamically add unicast routes or service routes into a JUNOS routing table. In other words, using libssd allows you to programmatically execute the CLI next-table command, as in the following example:

set routing-options static route next-table MYRI.inet.0

(For background and additional details about using libssd, see Route Manipulation and Management and Route Manager Application.)

The application should follow these steps:

  1. Call the ssd_request_route_table_lookup() function with the name of the routing table name that is the next hop.

  2. Retrieve the table ID using SSD_ROUTE_TABLE_LOOKUP_REPLY_GET_RTTID.

  3. Call the ssd_request_route_add() function to send a route add request to the SDK service daemon.

The following sample code illustrates these steps:

     * Some global definitions.
    ssd_sockaddr_un route_addr;
    ssd_sockaddr_un route_nh;
    ssd_sockaddr_un route_local;

     * Sample SDK application routine to add next-hop table route
     * This routine illustrates the mechanism for specifying the 
     * next-hop routing table entry.  You specify fields in the SSD 
     * parameter structure as shown.
    acme_client_add_route_tbl (
        int fd,                         /* SSD file descriptor      */
        char *ip_p,                     /* destination IP address   */
        char *iploc_p,                  /* local IP address         */
        u_int16_t rt_tbl                /* next-hop table-id        */
        struct ssd_route_parms rtp;

        /* Initialize the destination address structure. */
        memset(&route_addr, 0, sizeof(route_addr));
        ssd_setsocktype(&route_addr, SSD_GF_INET); = inet_addr(ip_p);
        /* Now set up the SSD parameter structure ... */
        memset(&rtp, 0, sizeof(rtp));

        /* Include the destination address information. */
        rtp.rta_dest = &route_addr;
        rtp.rta_prefixlen = 24;

        /* Add the preferences. */
        rtp.rta_preferences.rtm_val[0] = 1;
        rtp.rta_preferences.rtm_type[0] = SSD_RTM_VALUE_PRESENT;

        /* Add the routing table ID where the entry is to made. */
        rtp.rta_rtt = rttid;

         * Specify the next-hop information ...
         * These fields are required to key the back-end engine to add
         * a next-hop table-id   The rtb_id is obtained
         * by calling existing SSD name-to-id API routines.  No
         * other SSD parameter structure fields need to be set.

        rtp.rta_nhtype = SSD_RNH_TABLE;
        rtp.rta_gw_handle = 0;
        rtp.rta_n_gw = 1;
        rtp.rta_gateway[0].rtg_gwaddr = &route_nh;
        nh_idx_t_setval(rtp.rta_gateway[0].rtg_nhindex, rt_tbl);

        ssd_request_route_add(fd, &rtp, 0);


For additional sample code that adds a next-hop table, see the Route Manager sample application, which you can install in sandbox/src/sbin/route-manager/*. Documentation for adding the table is in the Sample Application Guide in Adding a Route or Next Hop (Using a Next-Hop Table).

Using libdfwd to Forward Traffic

Two functions in libdfwd allow you to re-direct traffic:

The following sample code shows how to use these functions.

For a more complex example of using libdfwd to redirect traffic to a next-hop table, see the code for the Policy Manager sample application in sandbox/src/sbin/ped/ped_filter.c and ped_filter.h.
static char *interface = NULL;
static char *rt_instance = NULL;
static struct option long_option[] =
             {{"routing-instance", required_argument, 0, 'r'},
              {"interface", required_argument, 0, 'i'},
              {"topology", required_argument, 0, 't'},
              {0, 0, 0, 0}
const parse_menu_t master_menu[] = {
    { "show", NULL, 0, NULL, NULL },
    { "quit", NULL, 0, NULL, NULL },    /**< called internally */
    { NULL, NULL, 0, NULL, NULL }

junos_dfw_session_handle_t ses_handle;
int test_typ;
u_int32_t acme_data = 0x600DDEED;

static void
test_ses_connect (junos_dfw_session_handle_t handle,
    junos_dfw_session_connect_return_t code,
    junos_dfw_client_id_t *client_id_list,
    int num_client_ids)
    int error, vrf_index;
    u_int16_t client_id;
    junos_dfw_filter_info_t filter_info;
    junos_dfw_term_info_t term_info;
    junos_dfw_trans_handle_t trans_hdl;
    junos_dfw_filter_attach_info_t attach_info;
    u_int32_t *acme_dt_p = NULL;
    u_int32_t ip_addr = 0x64646400;

    /* Basic setting up. */
    assert(num_client_ids == 1);
    client_id = client_id_list[0];
    error = junos_dfw_trans_purge(ses_handle, client_id_list, 1);
    assert(error == 0);

    /* Get the data we stored during session creation. */
    error = junos_dfw_session_user_data_get(ses_handle, (void **) &acme_dt_p);
    assert(error == 0);
    printf("Retrieved user data is ... %08X\n", (acme_dt_p) ? *acme_dt_p : 0);

    /* Create a filter. */
    filter_info.owner_client_id = (junos_dfw_client_id_t)client_id;
    strlcpy(filter_info.namestr_key, "route-inst-filter", 20);
    filter_info.type = JUNOS_DFW_FILTER_TYPE_CLASSIC;
    filter_info.addr_family = JUNOS_DFW_FILTER_AF_INET;

    /* Build a transaction. */
    error =
        junos_dfw_filter_trans_alloc(&filter_info, JUNOS_DFW_FILTER_OP_ADD,
    assert(error == 0);

    strlcpy(term_info.namestr_key, "route-term", 15);
    * = '\0';

    /* Start the requests. */
    error = junos_dfw_term_start(trans_hdl, &term_info, JUNOS_DFW_TERM_OP_ADD);
    assert (error == 0);

    /* Match either source or destination address. */
    error =
            &ip_addr, 24, JUNOS_DFW_FILTER_OP_MATCH);
    if (error) {
        printf("%s:%d junos_dfw_term_match_dest_prefix failed; %s\n",
            __func__, __LINE__, strerror(errno));
        /* Stop if positive case failed. */
        if (test_typ)
            assert (error == 0);

    error = junos_dfw_term_action_count(trans_hdl, "route-inst-counter");
    if (error) {
        printf("%s:%d junos_dfw_term_action_count failed; %s\n",
            __func__, __LINE__, strerror(errno));
        if (test_typ)
            assert (error == 0);
    if (!topology) {
        error = junos_dfw_term_action_redirect (trans_hdl, rt_instance);
        if (error) {
            printf("%s:%d junos_dfw_term_action_redirect failed; %s\n",
                    __func__, __LINE__, strerror(errno));
            if (test_typ)
                assert (error == 0);
    } else {
        error = junos_dfw_term_action_topology_redirect (trans_hdl,
                rt_instance, topology);
        if (error) {
            printf("%s:%d junos_dfw_term_action_topology_redirect failed; %s\n",
                    __func__, __LINE__, strerror(errno));
            if (test_typ)
                assert (error == 0);

    /* Close up transaction. */
    error = junos_dfw_term_end(trans_hdl);
    if (error) {
        printf("%s:%d junos_dfw_term_end failed; %s\n",
                __func__, __LINE__, strerror(errno));

© 2007-2009 Juniper Networks, Inc. All rights reserved. The information contained herein is confidential information of Juniper Networks, Inc., and may not be used, disclosed, distributed, modified, or copied without the prior written consent of Juniper Networks, Inc. in an express license. This information is subject to change by Juniper Networks, Inc. Juniper Networks, the Juniper Networks logo, and JUNOS are registered trademarks of Juniper Networks, Inc. in the United States and other countries. All other trademarks, service marks, registered trademarks, or registered service marks are the property of their respective owners.
Generated on Sun May 30 20:26:47 2010 for Juniper Networks Partner Solution Development Platform JUNOS SDK 10.2R1 by Doxygen 1.4.5