On Wed, May 30, 2018 at 7:10 PM, Daniel J Williams <djwil...@us.ibm.com>
wrote:

>
> >Can we use netdev struct to replace the index? Because the net device
> >may have different parameters, not merely index.
>
> We have a solo5_net_info structure, which has mtu and mac address at the
> moment and would likely need to grow at least to cover index.  The
> solo5_net_info call would also need to be updated to return info on the
> particular device (although perhaps we should think about having some of
> that in the start_info).
>
> >>> The only risk is breaking the solo5 interface currently used by
> >>> mirage and includeos.
>
> Are there examples of MirageOS unikernels that use two NICs on Xen or
> Unix?  That might be a starting point for understanding how the upper
> layers use multiple devices.  It sounds like there are already lots of
> examples of IncludeOS using multiple NICs, maybe a pointer to some of the
> relevant code will be helpful.
>

*IncludeOS notes below:*

IncludeOS has vm.json file inside each service which parsed and fed to qemu
and ukvm(recently added). For supporting multiple NICs, this is the
configuration.

{
  "image": "test_router.img",
  "mem" : 320,
  "net" : [{"device" : "virtio"},
           {"device" : "virtio"}],
}

Which gets translated to 2 network devices in qemu:

 sudo --preserve-env qemu-system-x86_64 -kernel
/Users/nikhil/includeos//includeos/chainloader -append "" -initrd
test_router "" -device virtio-net,netdev=net0 -netdev tap,id=net0, -device
virtio-net,netdev=net1 -netdev tap,id=net1, -m 320 -nographic


In the application, this is how the inet stacks are created on top of nic.
Note that IncludeOS uses an instance of inet/network stack per nic. Hence
if there are more NICs, there are multiple instances of inet/network stack

In test/net/integration/router we have this

  auto& inet = Inet::stack<0>();
  inet.network_config({  10,  0,  0, 42 },   // IP
                      { 255, 255, 0,  0 },   // Netmask
                      {  10,  0,  0,  1 } ); // Gateway

  auto& inet2 = Inet::stack<1>();
  inet2.network_config({  10,  42,  42, 43 },   // IP
                      { 255, 255, 255,  0 },   // Netmask
                      {  10,  42,  42,  2 } ); // Gateway


They pass an integer, 0, 1 as per nic index.
This eventually is called:

  // create network stack
  auto& nic = hw::Devices::get<hw::Nic>(N);
  return inet().create(nic, N, 0);

This is what the solo5 network driver class looks like and it is has single
mac address: Essentially, this is the NIC class

class Solo5Net : public net::Link_layer<net::Ethernet> {
private:
  MAC::Addr mac_addr;
}

This is its constructor:
(Note: *It uses the older solo5 API*)

Solo5Net::Solo5Net()
  : Link(Link_protocol{{this, &Solo5Net::transmit}, mac()}, bufstore_),
    packets_rx_{Statman::get().create(Stat::UINT64, device_name() +
".packets_rx").get_uint64()},
    packets_tx_{Statman::get().create(Stat::UINT64, device_name() +
".packets_tx").get_uint64()},
    bufstore_{NUM_BUFFERS, 2048u} // don't change this
{
  INFO("Solo5Net", "Driver initializing");
  mac_addr = MAC::Addr(*solo5_net_mac_str*());
}

With the updated solo5 API, this is what it might look like:

Solo5Net::Solo5Net()
  : Link(Link_protocol{{this, &Solo5Net::transmit}, mac()}, bufstore_),
    packets_rx_{Statman::get().create(Stat::UINT64, device_name() +
".packets_rx").get_uint64()},
    packets_tx_{Statman::get().create(Stat::UINT64, device_name() +
".packets_tx").get_uint64()},
    bufstore_{NUM_BUFFERS, 2048u} // don't change this
{
  uint8_t macaddr[6];
  INFO("Solo5Net", "Driver initializing");

  struct solo5_net_info ni;
  solo5_net_info(&ni);
  memcpy(macaddr, ni.mac_address, sizeof macaddr);
  char macaddr_s[(sizeof macaddr * 2) + 1];
  tohexs(macaddr_s, macaddr, sizeof macaddr);

  mac_addr = MAC::Addr(macaddr_s);
}

We can use solo5_app_main to specify the number of indices.
solo5_net_info, read and write APIs can be extended to pass the NIC
index.



> Thanks,
> Dan
>
>
>


-- 
Regards,
Nikhil

Reply via email to