[U-Boot] [PATCH 0/2] net: Netconsole port configuration and filtering

This series depends on this patch: http://patchwork.ozlabs.org/patch/174282/
Joe Hershberger (2): net: Allow netconsole settings to change after nc_start net: Filter incoming netconsole packets by IP
drivers/net/netconsole.c | 104 ++++++++++++++++++++++++++++++++--------------- include/net.h | 3 +- net/net.c | 1 + 3 files changed, 74 insertions(+), 34 deletions(-)

Refresh the netconsole settings from the env before each packet instead of only on netconsole init.
Signed-off-by: Joe Hershberger joe.hershberger@ni.com --- drivers/net/netconsole.c | 96 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 65 insertions(+), 31 deletions(-)
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index 86f5301..a31b95c 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -60,8 +60,69 @@ static void nc_timeout(void) net_set_state(NETLOOP_SUCCESS); }
+static int is_broadcast(IPaddr_t ip) +{ + static IPaddr_t netmask; + static IPaddr_t our_ip; + static int env_changed_id; + int env_id = get_env_id(); + + /* update only when the environment has changed */ + if (env_changed_id != env_id) { + netmask = getenv_IPaddr("netmask"); + our_ip = getenv_IPaddr("ipaddr"); + + env_changed_id = env_id; + } + + return (ip == ~0 || /* 255.255.255.255 */ + ((netmask & our_ip) == (netmask & ip) && /* on the same net */ + (netmask | ip) == ~0)); /* broadcast to our net */ +} + +static int refresh_settings_from_env(void) +{ + char *p; + static int env_changed_id; + int env_id = get_env_id(); + + /* update only when the environment has changed */ + if (env_changed_id != env_id) { + if (getenv("ncip")) { + nc_ip = getenv_IPaddr("ncip"); + if (!nc_ip) + return -1; /* ncip is 0.0.0.0 */ + p = strchr(getenv("ncip"), ':'); + if (p != NULL) { + nc_out_port = simple_strtoul(p + 1, NULL, 10); + nc_in_port = nc_out_port; + } + } else + nc_ip = ~0; /* ncip is not set, so broadcast */ + + p = getenv("ncoutport"); + if (p != NULL) + nc_out_port = simple_strtoul(p, NULL, 10); + p = getenv("ncinport"); + if (p != NULL) + nc_in_port = simple_strtoul(p, NULL, 10); + + if (is_broadcast(nc_ip)) + /* broadcast MAC address */ + memset(nc_ether, 0xff, sizeof(nc_ether)); + else + /* force arp request */ + memset(nc_ether, 0, sizeof(nc_ether)); + } + return 0; +} + +/** + * Called from NetLoop in net/net.c before each packet + */ void NcStart(void) { + refresh_settings_from_env(); if (!output_packet_len || memcmp(nc_ether, NetEtherNullAddr, 6)) { /* going to check for input packet */ net_set_udp_handler(nc_handler); @@ -148,41 +209,14 @@ static void nc_send_packet(const char *buf, int len)
static int nc_start(void) { - int netmask, our_ip; - char *p; + int retval;
nc_out_port = 6666; /* default port */ nc_in_port = nc_out_port;
- if (getenv("ncip")) { - - nc_ip = getenv_IPaddr("ncip"); - if (!nc_ip) - return -1; /* ncip is 0.0.0.0 */ - p = strchr(getenv("ncip"), ':'); - if (p != NULL) { - nc_out_port = simple_strtoul(p + 1, NULL, 10); - nc_in_port = nc_out_port; - } - } else - nc_ip = ~0; /* ncip is not set, so broadcast */ - - p = getenv("ncoutport"); - if (p != NULL) - nc_out_port = simple_strtoul(p, NULL, 10); - p = getenv("ncinport"); - if (p != NULL) - nc_in_port = simple_strtoul(p, NULL, 10); - - our_ip = getenv_IPaddr("ipaddr"); - netmask = getenv_IPaddr("netmask"); - - if (nc_ip == ~0 || /* 255.255.255.255 */ - ((netmask & our_ip) == (netmask & nc_ip) && /* on the same net */ - (netmask | nc_ip) == ~0)) /* broadcast to our net */ - memset(nc_ether, 0xff, sizeof(nc_ether)); - else - memset(nc_ether, 0, sizeof(nc_ether)); /* force arp request */ + retval = refresh_settings_from_env(); + if (retval != 0) + return retval;
/* * Initialize the static IP settings and buffer pointers

On Friday 17 August 2012 15:48:20 Joe Hershberger wrote:
--- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c
+static int refresh_settings_from_env(void)
this func always returns 0. why not change it to void to simplify the code (source and generated) ?
- char *p;
const -mike

Hi Mike,
On Fri, Aug 17, 2012 at 9:28 PM, Mike Frysinger vapier@gentoo.org wrote:
On Friday 17 August 2012 15:48:20 Joe Hershberger wrote:
--- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c
+static int refresh_settings_from_env(void)
this func always returns 0. why not change it to void to simplify the code (source and generated) ?
It returns -1 in the case where ncip == 0 in the environment.
char *p;
const
OK
Thanks, -Joe

Check the incoming packets' source IP address... if ncip isn't set to a broadcast address, only listen to the client at ncip.
Signed-off-by: Joe Hershberger joe.hershberger@ni.com --- drivers/net/netconsole.c | 8 ++++++-- include/net.h | 3 ++- net/net.c | 1 + 3 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index a31b95c..975507b 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -138,13 +138,17 @@ void NcStart(void) } }
-int nc_input_packet(uchar *pkt, unsigned dest, unsigned src, unsigned len) +int nc_input_packet(uchar *pkt, IPaddr_t src_ip, unsigned dest_port, + unsigned src_port, unsigned len) { int end, chunk;
- if (dest != nc_in_port || !len) + if (dest_port != nc_in_port || !len) return 0; /* not for us */
+ if (src_ip != nc_ip && !is_broadcast(nc_ip)) + return 0; /* not from our client */ + debug_cond(DEBUG_DEV_PKT, "input: "%*.*s"\n", len, len, pkt);
if (input_size == sizeof(input_buffer)) diff --git a/include/net.h b/include/net.h index 6d2d6cd..f0cf2ee 100644 --- a/include/net.h +++ b/include/net.h @@ -529,7 +529,8 @@ extern void NetReceive(uchar *, int);
#ifdef CONFIG_NETCONSOLE void NcStart(void); -int nc_input_packet(uchar *pkt, unsigned dest, unsigned src, unsigned len); +int nc_input_packet(uchar *pkt, IPaddr_t src_ip, unsigned dest_port, + unsigned src_port, unsigned len); #endif
/* diff --git a/net/net.c b/net/net.c index e8ff066..83fcbe5 100644 --- a/net/net.c +++ b/net/net.c @@ -1147,6 +1147,7 @@ NetReceive(uchar *inpkt, int len)
#ifdef CONFIG_NETCONSOLE nc_input_packet((uchar *)ip + IP_UDP_HDR_SIZE, + ntohl(ip->ip_src), ntohs(ip->udp_dst), ntohs(ip->udp_src), ntohs(ip->udp_len) - UDP_HDR_SIZE);

This series depends on this patch: http://patchwork.ozlabs.org/patch/174282/
Changes in v2: - Made string pointer const
Joe Hershberger (2): net: Allow netconsole settings to change after nc_start net: Filter incoming netconsole packets by IP
drivers/net/netconsole.c | 104 ++++++++++++++++++++++++++++++++--------------- include/net.h | 3 +- net/net.c | 1 + 3 files changed, 74 insertions(+), 34 deletions(-)

Refresh the netconsole settings from the env before each packet instead of only on netconsole init.
Signed-off-by: Joe Hershberger joe.hershberger@ni.com --- Changes in v2: - Made string pointer const
drivers/net/netconsole.c | 96 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 65 insertions(+), 31 deletions(-)
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index 86f5301..2e25fd5 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -60,8 +60,69 @@ static void nc_timeout(void) net_set_state(NETLOOP_SUCCESS); }
+static int is_broadcast(IPaddr_t ip) +{ + static IPaddr_t netmask; + static IPaddr_t our_ip; + static int env_changed_id; + int env_id = get_env_id(); + + /* update only when the environment has changed */ + if (env_changed_id != env_id) { + netmask = getenv_IPaddr("netmask"); + our_ip = getenv_IPaddr("ipaddr"); + + env_changed_id = env_id; + } + + return (ip == ~0 || /* 255.255.255.255 */ + ((netmask & our_ip) == (netmask & ip) && /* on the same net */ + (netmask | ip) == ~0)); /* broadcast to our net */ +} + +static int refresh_settings_from_env(void) +{ + const char *p; + static int env_changed_id; + int env_id = get_env_id(); + + /* update only when the environment has changed */ + if (env_changed_id != env_id) { + if (getenv("ncip")) { + nc_ip = getenv_IPaddr("ncip"); + if (!nc_ip) + return -1; /* ncip is 0.0.0.0 */ + p = strchr(getenv("ncip"), ':'); + if (p != NULL) { + nc_out_port = simple_strtoul(p + 1, NULL, 10); + nc_in_port = nc_out_port; + } + } else + nc_ip = ~0; /* ncip is not set, so broadcast */ + + p = getenv("ncoutport"); + if (p != NULL) + nc_out_port = simple_strtoul(p, NULL, 10); + p = getenv("ncinport"); + if (p != NULL) + nc_in_port = simple_strtoul(p, NULL, 10); + + if (is_broadcast(nc_ip)) + /* broadcast MAC address */ + memset(nc_ether, 0xff, sizeof(nc_ether)); + else + /* force arp request */ + memset(nc_ether, 0, sizeof(nc_ether)); + } + return 0; +} + +/** + * Called from NetLoop in net/net.c before each packet + */ void NcStart(void) { + refresh_settings_from_env(); if (!output_packet_len || memcmp(nc_ether, NetEtherNullAddr, 6)) { /* going to check for input packet */ net_set_udp_handler(nc_handler); @@ -148,41 +209,14 @@ static void nc_send_packet(const char *buf, int len)
static int nc_start(void) { - int netmask, our_ip; - char *p; + int retval;
nc_out_port = 6666; /* default port */ nc_in_port = nc_out_port;
- if (getenv("ncip")) { - - nc_ip = getenv_IPaddr("ncip"); - if (!nc_ip) - return -1; /* ncip is 0.0.0.0 */ - p = strchr(getenv("ncip"), ':'); - if (p != NULL) { - nc_out_port = simple_strtoul(p + 1, NULL, 10); - nc_in_port = nc_out_port; - } - } else - nc_ip = ~0; /* ncip is not set, so broadcast */ - - p = getenv("ncoutport"); - if (p != NULL) - nc_out_port = simple_strtoul(p, NULL, 10); - p = getenv("ncinport"); - if (p != NULL) - nc_in_port = simple_strtoul(p, NULL, 10); - - our_ip = getenv_IPaddr("ipaddr"); - netmask = getenv_IPaddr("netmask"); - - if (nc_ip == ~0 || /* 255.255.255.255 */ - ((netmask & our_ip) == (netmask & nc_ip) && /* on the same net */ - (netmask | nc_ip) == ~0)) /* broadcast to our net */ - memset(nc_ether, 0xff, sizeof(nc_ether)); - else - memset(nc_ether, 0, sizeof(nc_ether)); /* force arp request */ + retval = refresh_settings_from_env(); + if (retval != 0) + return retval;
/* * Initialize the static IP settings and buffer pointers

Check the incoming packets' source IP address... if ncip isn't set to a broadcast address, only listen to the client at ncip.
Signed-off-by: Joe Hershberger joe.hershberger@ni.com ---
drivers/net/netconsole.c | 8 ++++++-- include/net.h | 3 ++- net/net.c | 1 + 3 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index 2e25fd5..b0cc81c 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -138,13 +138,17 @@ void NcStart(void) } }
-int nc_input_packet(uchar *pkt, unsigned dest, unsigned src, unsigned len) +int nc_input_packet(uchar *pkt, IPaddr_t src_ip, unsigned dest_port, + unsigned src_port, unsigned len) { int end, chunk;
- if (dest != nc_in_port || !len) + if (dest_port != nc_in_port || !len) return 0; /* not for us */
+ if (src_ip != nc_ip && !is_broadcast(nc_ip)) + return 0; /* not from our client */ + debug_cond(DEBUG_DEV_PKT, "input: "%*.*s"\n", len, len, pkt);
if (input_size == sizeof(input_buffer)) diff --git a/include/net.h b/include/net.h index 6d2d6cd..f0cf2ee 100644 --- a/include/net.h +++ b/include/net.h @@ -529,7 +529,8 @@ extern void NetReceive(uchar *, int);
#ifdef CONFIG_NETCONSOLE void NcStart(void); -int nc_input_packet(uchar *pkt, unsigned dest, unsigned src, unsigned len); +int nc_input_packet(uchar *pkt, IPaddr_t src_ip, unsigned dest_port, + unsigned src_port, unsigned len); #endif
/* diff --git a/net/net.c b/net/net.c index e8ff066..83fcbe5 100644 --- a/net/net.c +++ b/net/net.c @@ -1147,6 +1147,7 @@ NetReceive(uchar *inpkt, int len)
#ifdef CONFIG_NETCONSOLE nc_input_packet((uchar *)ip + IP_UDP_HDR_SIZE, + ntohl(ip->ip_src), ntohs(ip->udp_dst), ntohs(ip->udp_src), ntohs(ip->udp_len) - UDP_HDR_SIZE);
participants (3)
-
Joe Hershberger
-
Joe Hershberger
-
Mike Frysinger