rtnetlink, setting gateway on eth1 fails

rtnetlink, setting gateway on eth1 fails

Post by Scott Derric » Fri, 30 Jul 2004 02:27:13



I'm trying to set the gateway on a multiNIC machine.  The code below works
fine for eth0 but does nothing for eth1 or eth2

the parameter gate == IP in dotted notatio, the parameter device == "eth0",
"eth1" or "eth2"

I'm using the decimal equivelant of eth"0"  for the RTA_OIF, so eth0 would
be decimal 0, eth1 woudl be decimal 1, etc..

what am I doing wrong that would allow this to work fine for eth0 but not
the other NIC's.  I can use the route program and add or delete gateways to
al theNIC's.

thanks, Scott

*****************code follows*******************

const char *envLinux :: ip_gateway ( const char *gate, const char *device )
{
 ////////////////////////////////////////////////////////////////////////
 //
 // OVERLOAD  IConfigIP
 //
 // PURPOSE
 //  - Sets/retreives the current IP gateway address.
 //
 // PARAMETERS
 //  - addr specifies the new gateway address (set to NULL to retrieve)
 //
 // RETURN VALUE
 //  Ptr. to current gateway address
 //
 ////////////////////////////////////////////////////////////////////////
 int                     inet_sock   = -1, ret;
 IException              *ex             = NULL;
 char                     GATEWAY[9];
 struct in_addr           tempAddr;
 int ind = 0;

 struct{
  struct nlmsghdr netlink_header;
  struct rtmsg    rt_message;
  char            buffer[1024];
 }request;

 try
 {
  ind = atoi(device + 3);

  if(!strcmp(gate, "0.0.0.0") == 0) // add a gateway
  {
   inet_sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
   if (inet_sock == -1)
   {
    printf( "ip_gateway : Unable to create a socket" );
    fflush(stdout);
    return 0;
   }

   memset(&request, 0, sizeof(request));
   request.netlink_header.nlmsg_len =NLMSG_LENGTH(sizeof(struct rtmsg));
   request.netlink_header.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE;
   request.netlink_header.nlmsg_type = RTM_NEWROUTE;
   request.rt_message.rtm_family = AF_INET;
   request.rt_message.rtm_table = RT_TABLE_MAIN;

   request.rt_message.rtm_protocol = RTPROT_BOOT;
   request.rt_message.rtm_scope = RT_SCOPE_UNIVERSE;
   request.rt_message.rtm_type = RTN_UNICAST;

   if(inet_aton(gate, &tempAddr))
     addattr_l(&request.netlink_header, sizeof(request),
       RTA_GATEWAY, (void*)&(tempAddr.s_addr), 4);

   if(inet_aton("0.0.0.0", &tempAddr))
    addattr_l(&request.netlink_header, sizeof(request),
      RTA_DST, (void*)&(tempAddr.s_addr), 4);

   addattr32(&request.netlink_header, sizeof(request), RTA_OIF, ind);

   struct sockaddr_nl nladdr;
   struct iovec iov ={(void*)&request,request.netlink_header.nlmsg_len};
   struct msghdr msg = {
    (void*)&nladdr,
    sizeof(nladdr),
    &iov,
    1,
    NULL,
    0,
    0};
   qq
   memset(&nladdr, 0, sizeof(nladdr));
   nladdr.nl_family = AF_NETLINK;
   nladdr.nl_pid = 0;
   nladdr.nl_groups = 0;

   ret = sendmsg(inet_sock, &msg, 0);

   if (ret < 1)
   {
    printf("ip_gateway: send returned %d error %d\n", ret, errno);
    fflush(stdout);
   }
  } // if
 } // try
 catch ( IException *_ex )
 {
  ex = _ex;
 } // catch

 // Clean up
 if (inet_sock != -1) close ( inet_sock );
 if (ex != NULL)   throw ex;
 else
  printf ( "%s: Gateway : %s on %s\n", name, tempstr, device  );

 return tempstr;

Quote:} // ip_gateway