Re: Name of the primary network interface, how to find in bsp header files?

2020-08-09 Thread Chris Johns
On 10/8/20 4:20 am, Heinz Junkes wrote:
> Hello, Chris,
> 
> with libbsd I also realized this with the concept you suggested (still beta 
> development):
> 
> ...
> sc = rtems_bsd_initialize();
> assert(sc == RTEMS_SUCCESSFUL);
> 
> /* Let the callout timer allocate its resources */
> sc = rtems_task_wake_after(2);
> assert(sc == RTEMS_SUCCESSFUL);
> 
> rtems_bsd_ifconfig_lo0();
> 
> //  lookup available network interfaces
> char ifnamebuf[IF_NAMESIZE];
> char *ifname;
> // get primary network interface
> ifname = if_indextoname(1, [0]);
> assert(ifname != NULL);
> printf("\n* Primary Network interface : %s *\n", ifname);
> 
> default_network_dhcpcd();
> 
> // implement DHCP hook  ... and wait for acknowledge
> dhcpDone = epicsEventMustCreate(epicsEventEmpty);
> rtems_dhcpcd_add_hook(_hook);

Is it a requirement for EPICS systems to be DHCP?

> // wait for dhcp done ... should be if SYNCDHCP is used
> epicsEventWaitStatus stat;
> int counter = 10;
> do {
> printf("\n  Wait for DHCP done ...\n");
> stat = epicsEventWaitWithTimeout(dhcpDone, 5.0);
> } while ((stat == epicsEventWaitTimeout) && (--counter > 0));
> if (stat == epicsEventOK)
> epicsEventDestroy(dhcpDone);
> else
> printf("\n  dhcpDone Event Unknown state %d\n", stat);
> …
> 
> static void
> default_network_dhcpcd(void)
> {
> static const char default_cfg[] = "clientid FHI test client\n";
> rtems_status_code sc;
> int fd;
> int rv;
> ssize_t n;
> fd = open("/etc/dhcpcd.conf", O_CREAT | O_WRONLY,
> S_IRWXU | S_IRWXG | S_IRWXO);
> assert(fd >= 0);
> 
> n = write(fd, default_cfg, sizeof(default_cfg) - 1);
> assert(n == (ssize_t) sizeof(default_cfg) - 1);
> 
> 
> static const char fhi_cfg[] = "nodhcp6\nipv4only\noption ntp_servers\noption 
> rtems_cmdline\n";

What is `option rtems_cmdline? Is this a special EPICS option?

There is no `allowinterfaces` so it seems this is for a single interface 
machine.

While this may work for the qemu testrig we will need something more for the RSB
configuration.

> 
> n = write(fd, fhi_cfg, sizeof(fhi_cfg) - 1);
> assert(n == (ssize_t) sizeof(fhi_cfg) - 1);
> 
> rv = close(fd);
> assert(rv == 0);
> 
> sc = rtems_dhcpcd_start(NULL);
> assert(sc == RTEMS_SUCCESSFUL);
> }
> 
> static void
> dhcpcd_hook_handler(rtems_dhcpcd_hook *hook, char *const *env)
> {
> int bound = 0;
> char iName[16];
> char *name;
> char *value;
> 
> (void)hook;
> 
> while (*env != NULL) {
> name = strtok(*env,"=");
> value = strtok(NULL,"=");
> printf("all out ---> %s = %s\n", name, value);
> if (!strncmp(name, "interface", 9) && !strcmp(value,  
> NET_CFG_INTERFACE_0))
>  strncpy(iName, value, 16);
> if (!strncmp(name, "reason", 6) && !strncmp(value, "BOUND", 
> 5)){
>   printf ("Interface %s bounded\n", iName);
>   bound = 1;
> }
> if (bound) {
>   // as there is no ntp-support in rtems-libbsd, we call our 
> own client
>   if(!strncmp(name, "new_ntp_servers", 15))
> strcpy(rtemsInit_NTP_server_ip,value);
>   if(!strncmp(name, "new_host_name", 13))
> sethostname (value, strlen (value));
>   if(!strncmp(name, "new_tftp_server_name", 20)){
> printf(" new_tftp_server_name : %s\n", value);
> strncpy(rtems_bsdnet_bootp_server_name,value, 
> sizeof(bootp_server_name_init));
>   }
> 
>   printf("---> %s = %s\n", name, value);
> }
> ++env;
> }
> if (bound)
>   epicsEventSignal(dhcpDone);
> }
> 
> static rtems_dhcpcd_hook dhcpcd_hook = {
> .name = "ioc boot",
> .handler = dhcpcd_hook_handler
> };
> 
> But the biggest problem here is that on the test-CI-system (travis, appveyor, 
> etc.) a dhcp-server, 
> ntp-server, nfs-server and complex routing structures for e.g. qemu must be 
> provided. 

Yes I am sure it is complicated. Is your work just focused on this test set up?

> There it is easier to use environment variables.

In the hook I suspect it is the simplest.

Chris

> 
> Many greetings
> Heinz 
> 
> 
>> On 9. Aug 2020, at 02:44, Chris Johns  wrote:
>>
>>> nging configuration. And likely only one NIC.
>>
>> Agreed and it works for a testsuite to some extent. Network tests are hard
>> because you need a very controlled network set up to make then work.
>>
>>> It was used in the network demos for the legacy stack so if we want to
>>> eliminate it completely, it would be good to find a recommended way to
>>> look up the interface name and put it into the legacy configuration
>>> tables.
>>>
>>> https://git.rtems.org/network-demos/tree  
>>>
>>> Yes... I know we all 

Re: Name of the primary network interface, how to find in bsp header files?

2020-08-09 Thread Heinz Junkes
Hello, Chris,

with libbsd I also realized this with the concept you suggested (still beta 
development):

...
sc = rtems_bsd_initialize();
assert(sc == RTEMS_SUCCESSFUL);

/* Let the callout timer allocate its resources */
sc = rtems_task_wake_after(2);
assert(sc == RTEMS_SUCCESSFUL);

rtems_bsd_ifconfig_lo0();

//  lookup available network interfaces
char ifnamebuf[IF_NAMESIZE];
char *ifname;
// get primary network interface
ifname = if_indextoname(1, [0]);
assert(ifname != NULL);
printf("\n* Primary Network interface : %s *\n", ifname);

default_network_dhcpcd();

// implement DHCP hook  ... and wait for acknowledge
dhcpDone = epicsEventMustCreate(epicsEventEmpty);
rtems_dhcpcd_add_hook(_hook);

// wait for dhcp done ... should be if SYNCDHCP is used
epicsEventWaitStatus stat;
int counter = 10;
do {
printf("\n  Wait for DHCP done ...\n");
stat = epicsEventWaitWithTimeout(dhcpDone, 5.0);
} while ((stat == epicsEventWaitTimeout) && (--counter > 0));
if (stat == epicsEventOK)
epicsEventDestroy(dhcpDone);
else
printf("\n  dhcpDone Event Unknown state %d\n", stat);
…

static void
default_network_dhcpcd(void)
{
static const char default_cfg[] = "clientid FHI test client\n";
rtems_status_code sc;
int fd;
int rv;
ssize_t n;
fd = open("/etc/dhcpcd.conf", O_CREAT | O_WRONLY,
S_IRWXU | S_IRWXG | S_IRWXO);
assert(fd >= 0);

n = write(fd, default_cfg, sizeof(default_cfg) - 1);
assert(n == (ssize_t) sizeof(default_cfg) - 1);


static const char fhi_cfg[] = "nodhcp6\nipv4only\noption ntp_servers\noption 
rtems_cmdline\n";

n = write(fd, fhi_cfg, sizeof(fhi_cfg) - 1);
assert(n == (ssize_t) sizeof(fhi_cfg) - 1);

rv = close(fd);
assert(rv == 0);

sc = rtems_dhcpcd_start(NULL);
assert(sc == RTEMS_SUCCESSFUL);
}

static void
dhcpcd_hook_handler(rtems_dhcpcd_hook *hook, char *const *env)
{
int bound = 0;
char iName[16];
char *name;
char *value;

(void)hook;

while (*env != NULL) {
name = strtok(*env,"=");
value = strtok(NULL,"=");
printf("all out ---> %s = %s\n", name, value);
if (!strncmp(name, "interface", 9) && !strcmp(value,  
NET_CFG_INTERFACE_0))
 strncpy(iName, value, 16);
if (!strncmp(name, "reason", 6) && !strncmp(value, "BOUND", 5)){
  printf ("Interface %s bounded\n", iName);
  bound = 1;
}
if (bound) {
  // as there is no ntp-support in rtems-libbsd, we call our 
own client
  if(!strncmp(name, "new_ntp_servers", 15))
strcpy(rtemsInit_NTP_server_ip,value);
  if(!strncmp(name, "new_host_name", 13))
sethostname (value, strlen (value));
  if(!strncmp(name, "new_tftp_server_name", 20)){
printf(" new_tftp_server_name : %s\n", value);
strncpy(rtems_bsdnet_bootp_server_name,value, 
sizeof(bootp_server_name_init));
  }

  printf("---> %s = %s\n", name, value);
}
++env;
}
if (bound)
  epicsEventSignal(dhcpDone);
}

static rtems_dhcpcd_hook dhcpcd_hook = {
.name = "ioc boot",
.handler = dhcpcd_hook_handler
};

But the biggest problem here is that on the test-CI-system (travis, appveyor, 
etc.) a dhcp-server, 
ntp-server, nfs-server and complex routing structures for e.g. qemu must be 
provided. 
There it is easier to use environment variables.

Many greetings
Heinz 


> On 9. Aug 2020, at 02:44, Chris Johns  wrote:
> 
>> nging configuration. And likely only one NIC.
> 
> Agreed and it works for a testsuite to some extent. Network tests are hard
> because you need a very controlled network set up to make then work.
> 
>> It was used in the network demos for the legacy stack so if we want to
>> eliminate it completely, it would be good to find a recommended way to
>> look up the interface name and put it into the legacy configuration
>> tables.
>> 
>> https://git.rtems.org/network-demos/tree  
>> 
>> Yes... I know we all want to see it removed and everyone move to
>> libbsd. But I don't think that is realistic to expect. The more realistic
>> solution is to move it to its own build tree and freeze it. It is there
>> and we encourage people to use libbsd. But it does offer a solution
>> for older target boards. The old stack is also all that is supported by
>> many EPICS boards. Outside of EPICS users, even the SPARC BSPs 
>> haven't been converted yet.
> 
> Yes we should move it out of the main tree and have it becomes an available
> optional package. It can be maintained by those with an active interest in it.
> 
> It has some bugs ... we found one last year with the arp cache and Windows. 
> The
> solution was a hack to set the arp aging timer 

Re: Name of the primary network interface, how to find in bsp header files?

2020-08-08 Thread Chris Johns
On 9/8/20 6:51 am, Joel Sherrill wrote:
> On Sat, Aug 8, 2020 at 7:09 AM Heinz Junkes  > wrote:
> 
> Hallo Chris,
> I think there's been a misunderstanding.

This is more than likely. I do not know what EPICS requires for network
initialisation.

Is it possible for you describe what is needed or point me to some documentation
or existing EPICS code for the legacy stack?

> I have implemented the following in the EPICS rtems_init.c :

For libbsd?

> ...
> sc = rtems_bsd_initialize();
> assert (sc == RTEMS_SUCCESSFUL)
> /* Let the callout timer allocate its resources */
> sc = rtems_task_wake_after(2);
> assert (sc == RTEMS_SUCCESSFUL)

With DHCP and the default route the normal FreeBSD timeout is 30seconds.

Have you looked into the rc.conf support in libbsd? See below. I encourage all
users of libbsd to look at this approach.

> rtems_bsd_ifconfig_lo0();
> 
> /* lookup primary network interface */
> char ifnamebuf[IF_NAMESIZE];
> char *prim_ifname;
> prim_ifname = if_indextoname(1, [0]);

Why 1?

> assert(prim_ifname != NULL);

For libbsd I create an `/etc/rc.conf` file 

#
# LibBSD Configuration
#
hostname="foobar"
ifconfig_cgem0="DHCP rxcsum txcsum"
ifconfig_cgem0_alias0="ether 10:10:10:10:10:10"
dhcpcd_priority="200"
dhcpcd_options="--nobackground --timeout 10"

then call...

bool network_start_network(int timeout, bool trace)
{
  int  r;
  if (timeout == 0)
timeout = 30;
  sleep(2);
  r = rtems_bsd_run_etc_rc_conf(timeout, trace);
  if (r < 0)
printf("error: loading BSD /etc/rc.conf failed: %s\n", strerror(errno));

  /* start any other services */

  return true;
}

If the critical information for the rc.conf could be captured so it can be a
system specific configuration then it would help.

> Speaking from a standard perspective, this is the right thing to do.
> Assuming the code is correct. :)

Is the valid interface index in the call to if_indextoname a 1, 2 or something 
else?

> I agree that  RTEMS_BSP_NETWORK_DRIVER_NAME is problematic.
> It wasn't reliable on anything but embedded boards with strict and 
> unchanging configuration. And likely only one NIC.

Agreed and it works for a testsuite to some extent. Network tests are hard
because you need a very controlled network set up to make then work.

> It was used in the network demos for the legacy stack so if we want to
> eliminate it completely, it would be good to find a recommended way to
> look up the interface name and put it into the legacy configuration
> tables.
> 
> https://git.rtems.org/network-demos/tree  
> 
> Yes... I know we all want to see it removed and everyone move to
> libbsd. But I don't think that is realistic to expect. The more realistic
> solution is to move it to its own build tree and freeze it. It is there
> and we encourage people to use libbsd. But it does offer a solution
> for older target boards. The old stack is also all that is supported by
> many EPICS boards. Outside of EPICS users, even the SPARC BSPs 
> haven't been converted yet.

Yes we should move it out of the main tree and have it becomes an available
optional package. It can be maintained by those with an active interest in it.

It has some bugs ... we found one last year with the arp cache and Windows. The
solution was a hack to set the arp aging timer to a very large number.

> Anyway... I'd love to see RTEMS_BSP_NETWORK_DRIVER_NAME
> killed completely but we need to address filling in the legacy network
> stack table before the stack is initialized enough to even know the 
> interface names.

Yes, but Heinz is working on libbsd support for EPICS or have I missed 
something?

> Perhaps this turns into an application provided method for the legacy
> stack? Just a thought.

Yes that works.

Chris

> > On 8. Aug 2020, at 03:50, Chris Johns  > wrote:
> >
> > On 8/8/20 5:12 am, Heinz Junkes wrote:
> >>
> >> it works great with the libbsd-stack.
> >
> > I do not think it is a good idea rely on the 
> RTEMS_BSP_NETWORK_DRIVER_NAME
> > setting in libbsd. I have not questioned it before now as it has been 
> used
> > internally in the tests but exporting it as an interface is something 
> else. It
> > works for a specific case of target but it does not for others, for
> example the
> > Xilinx Zynq has 2 MACs (cgem0, cgem1), a PC has a wide range of 
> interfaces.
> >
> >> That is then also definitely the way to go.
> >
> > How would cgem1 on a Zynq be specified if RTEMS_BSP_NETWORK_DRIVER_NAME 
> is
> > cgem0? Also there is nothing stopping me changing
> RTEMS_BSP_NETWORK_DRIVER_NAME
> > to cgem1 so how does that get handled?
> >
> > After 25 years doing this I have learnt to be careful about what we 
> export and
> > depend on.
> >
> >> I just remembered in the legacy stack that the network driver name
> >> was set in some 

Re: Name of the primary network interface, how to find in bsp header files?

2020-08-08 Thread Joel Sherrill
On Sat, Aug 8, 2020 at 7:09 AM Heinz Junkes 
wrote:

> Hallo Chris,
> I think there's been a misunderstanding.
> I have implemented the following in the EPICS rtems_init.c :
>
> ...
> sc = rtems_bsd_initialize();
> assert (sc == RTEMS_SUCCESSFUL)
> /* Let the callout timer allocate its resources */
> sc = rtems_task_wake_after(2);
> assert (sc == RTEMS_SUCCESSFUL)
>
> rtems_bsd_ifconfig_lo0();
>
> /* lookup primary network interface */
> char ifnamebuf[IF_NAMESIZE];
> char *prim_ifname;
> prim_ifname = if_indextoname(1, [0]);
> assert(prim_ifname != NULL);
>

Speaking from a standard perspective, this is the right thing to do.
Assuming the code is correct. :)

I agree that  RTEMS_BSP_NETWORK_DRIVER_NAME is problematic.
It wasn't reliable on anything but embedded boards with strict and
unchanging configuration. And likely only one NIC.

It was used in the network demos for the legacy stack so if we want to
eliminate it completely, it would be good to find a recommended way to
look up the interface name and put it into the legacy configuration
tables.

https://git.rtems.org/network-demos/tree

Yes... I know we all want to see it removed and everyone move to
libbsd. But I don't think that is realistic to expect. The more realistic
solution is to move it to its own build tree and freeze it. It is there
and we encourage people to use libbsd. But it does offer a solution
for older target boards. The old stack is also all that is supported by
many EPICS boards. Outside of EPICS users, even the SPARC BSPs
haven't been converted yet.

Anyway... I'd love to see RTEMS_BSP_NETWORK_DRIVER_NAME
killed completely but we need to address filling in the legacy network
stack table before the stack is initialized enough to even know the
interface names.

Perhaps this turns into an application provided method for the legacy
stack? Just a thought.

--joel


> …
>
> Heinz
>
>
> > On 8. Aug 2020, at 03:50, Chris Johns  wrote:
> >
> > On 8/8/20 5:12 am, Heinz Junkes wrote:
> >>
> >> it works great with the libbsd-stack.
> >
> > I do not think it is a good idea rely on the
> RTEMS_BSP_NETWORK_DRIVER_NAME
> > setting in libbsd. I have not questioned it before now as it has been
> used
> > internally in the tests but exporting it as an interface is something
> else. It
> > works for a specific case of target but it does not for others, for
> example the
> > Xilinx Zynq has 2 MACs (cgem0, cgem1), a PC has a wide range of
> interfaces.
> >
> >> That is then also definitely the way to go.
> >
> > How would cgem1 on a Zynq be specified if RTEMS_BSP_NETWORK_DRIVER_NAME
> is
> > cgem0? Also there is nothing stopping me changing
> RTEMS_BSP_NETWORK_DRIVER_NAME
> > to cgem1 so how does that get handled?
> >
> > After 25 years doing this I have learnt to be careful about what we
> export and
> > depend on.
> >
> >> I just remembered in the legacy stack that the network driver name
> >> was set in some BSPs. But this was probably not continuous. And with
> the new ones, it is no longer possible.
> >
> > As a default it may be OK however it would be nice or important to allow
> this to
> > be changed.
> >
> > How does an EPICS build for Linux on a PC deal with this given there is
> a large
> > number of possible interface names?
> >
> > Chris
>
> ___
> devel mailing list
> devel@rtems.org
> http://lists.rtems.org/mailman/listinfo/devel
___
devel mailing list
devel@rtems.org
http://lists.rtems.org/mailman/listinfo/devel

Re: Name of the primary network interface, how to find in bsp header files?

2020-08-08 Thread Heinz Junkes
Hallo Chris,
I think there's been a misunderstanding.
I have implemented the following in the EPICS rtems_init.c :

...
sc = rtems_bsd_initialize();
assert (sc == RTEMS_SUCCESSFUL)
/* Let the callout timer allocate its resources */
sc = rtems_task_wake_after(2);
assert (sc == RTEMS_SUCCESSFUL)

rtems_bsd_ifconfig_lo0();

/* lookup primary network interface */
char ifnamebuf[IF_NAMESIZE];
char *prim_ifname;
prim_ifname = if_indextoname(1, [0]);
assert(prim_ifname != NULL);
…

Heinz


> On 8. Aug 2020, at 03:50, Chris Johns  wrote:
> 
> On 8/8/20 5:12 am, Heinz Junkes wrote:
>> 
>> it works great with the libbsd-stack.
> 
> I do not think it is a good idea rely on the RTEMS_BSP_NETWORK_DRIVER_NAME
> setting in libbsd. I have not questioned it before now as it has been used
> internally in the tests but exporting it as an interface is something else. It
> works for a specific case of target but it does not for others, for example 
> the
> Xilinx Zynq has 2 MACs (cgem0, cgem1), a PC has a wide range of interfaces.
> 
>> That is then also definitely the way to go.
> 
> How would cgem1 on a Zynq be specified if RTEMS_BSP_NETWORK_DRIVER_NAME is
> cgem0? Also there is nothing stopping me changing 
> RTEMS_BSP_NETWORK_DRIVER_NAME
> to cgem1 so how does that get handled?
> 
> After 25 years doing this I have learnt to be careful about what we export and
> depend on.
> 
>> I just remembered in the legacy stack that the network driver name
>> was set in some BSPs. But this was probably not continuous. And with the new 
>> ones, it is no longer possible.
> 
> As a default it may be OK however it would be nice or important to allow this 
> to
> be changed.
> 
> How does an EPICS build for Linux on a PC deal with this given there is a 
> large
> number of possible interface names?
> 
> Chris



smime.p7s
Description: S/MIME cryptographic signature
___
devel mailing list
devel@rtems.org
http://lists.rtems.org/mailman/listinfo/devel

Re: Name of the primary network interface, how to find in bsp header files?

2020-08-07 Thread Chris Johns
On 8/8/20 5:12 am, Heinz Junkes wrote:
> 
> it works great with the libbsd-stack.

I do not think it is a good idea rely on the RTEMS_BSP_NETWORK_DRIVER_NAME
setting in libbsd. I have not questioned it before now as it has been used
internally in the tests but exporting it as an interface is something else. It
works for a specific case of target but it does not for others, for example the
Xilinx Zynq has 2 MACs (cgem0, cgem1), a PC has a wide range of interfaces.

> That is then also definitely the way to go.

How would cgem1 on a Zynq be specified if RTEMS_BSP_NETWORK_DRIVER_NAME is
cgem0? Also there is nothing stopping me changing RTEMS_BSP_NETWORK_DRIVER_NAME
to cgem1 so how does that get handled?

After 25 years doing this I have learnt to be careful about what we export and
depend on.

> I just remembered in the legacy stack that the network driver name
> was set in some BSPs. But this was probably not continuous. And with the new 
> ones, it is no longer possible.

As a default it may be OK however it would be nice or important to allow this to
be changed.

How does an EPICS build for Linux on a PC deal with this given there is a large
number of possible interface names?

Chris
___
devel mailing list
devel@rtems.org
http://lists.rtems.org/mailman/listinfo/devel


Re: Name of the primary network interface, how to find in bsp header files?

2020-08-07 Thread Heinz Junkes
Danke,

it works great with the libbsd-stack.

That is then also definitely the way to go. I just remembered in the legacy 
stack that the network driver name
was set in some BSPs. But this was probably not continuous. And with the new 
ones, it is no longer possible. 
Heinz


> On 7. Aug 2020, at 14:17, Sebastian Huber 
>  wrote:
> 
> On 07/08/2020 13:39, Heinz Junkes wrote:
> 
>> Can I get the name of the primary network interface from the header files of 
>> a target-bsp?
> 
> Some BSPs have an RTEMS_BSP_NETWORK_DRIVER_NAME define.
> 
> With libbsd you can try something like this:
> 
> char ifnamebuf[IF_NAMESIZE];
> char *ifname;
> 
> 
> ifname = if_indextoname(1, [0]);
> assert(ifname != NULL);
> 



smime.p7s
Description: S/MIME cryptographic signature
___
devel mailing list
devel@rtems.org
http://lists.rtems.org/mailman/listinfo/devel

Re: Name of the primary network interface, how to find in bsp header files?

2020-08-07 Thread Sebastian Huber

On 07/08/2020 13:39, Heinz Junkes wrote:


Can I get the name of the primary network interface from the header files of a 
target-bsp?


Some BSPs have an RTEMS_BSP_NETWORK_DRIVER_NAME define.

With libbsd you can try something like this:

    char ifnamebuf[IF_NAMESIZE];
    char *ifname;


    ifname = if_indextoname(1, [0]);
    assert(ifname != NULL);

___
devel mailing list
devel@rtems.org
http://lists.rtems.org/mailman/listinfo/devel