summaryrefslogtreecommitdiff
path: root/cleopatre
diff options
context:
space:
mode:
authorlefranc2010-06-22 07:22:04 +0000
committerlefranc2010-06-22 07:22:04 +0000
commit90b32da05699143e24738606a297160ff0b36799 (patch)
tree4c1cd5d4286e63fd28d8a246ae34c6bd9f169133 /cleopatre
parent6bcf888d04053aa4c8145f28da1fd4719835158e (diff)
cleo/appli/managerd: listen to 'lo' interface, refs #1669
- managerd listen to br0, lo and nl_mme interface - lo is used by local applications sending local MME git-svn-id: svn+ssh://pessac/svn/cesar/trunk@7243 017c9cb6-072f-447c-8318-d5b54f68fe89
Diffstat (limited to 'cleopatre')
-rw-r--r--cleopatre/application/managerd/inc/bridge.h4
-rw-r--r--cleopatre/application/managerd/inc/managerd.h3
-rw-r--r--cleopatre/application/managerd/src/bridge.c81
-rw-r--r--cleopatre/application/managerd/src/managerd.c10
4 files changed, 73 insertions, 25 deletions
diff --git a/cleopatre/application/managerd/inc/bridge.h b/cleopatre/application/managerd/inc/bridge.h
index 4ef79d70a1..3a29d15055 100644
--- a/cleopatre/application/managerd/inc/bridge.h
+++ b/cleopatre/application/managerd/inc/bridge.h
@@ -27,6 +27,7 @@
/** Interfaces name */
#define BR_IFNAME "br0"
+#define LO_IFNAME "lo"
#define ETH_IFNAME "eth0"
/** Reception timeout in seconds */
@@ -56,9 +57,10 @@ enum bridge_status bridge_processing(struct managerd_ctx *ctx, uint8_t *buffer,
* \param ctx managerd context.
* \param buffer frame pointer.
* \param len length allowed.
+ * \param is_local boolean; TRUE: get packet from loopback, else: get packet from bridge
* \return received length or error code.
*/
-int bridge_receive(struct managerd_ctx *ctx, uint8_t *buffer, int len);
+int bridge_receive(struct managerd_ctx *ctx, uint8_t *buffer, int len, int is_local);
/**
* Send a frame to BR interface.
diff --git a/cleopatre/application/managerd/inc/managerd.h b/cleopatre/application/managerd/inc/managerd.h
index 7591b49ebf..d18e16a946 100644
--- a/cleopatre/application/managerd/inc/managerd.h
+++ b/cleopatre/application/managerd/inc/managerd.h
@@ -36,12 +36,11 @@
/** Context structure */
struct managerd_ctx {
int sock_br; /* bridge socket */
+ int sock_lo; /* loopback socket */
int sock_mme; /* netlink socket for rx/tx MME to/from AV stack */
int gpio_fd;
struct sockaddr_ll br_sll;
struct sockaddr_nl mme_snl;
- socklen_t br_sll_sz;
- struct ifreq br_ifr;
uint8_t br_mac_addr[ETH_ALEN];
union gpio_info sc_gpio;
union gpio_info led_gpio;
diff --git a/cleopatre/application/managerd/src/bridge.c b/cleopatre/application/managerd/src/bridge.c
index 6ca8e2334d..3d6c13a973 100644
--- a/cleopatre/application/managerd/src/bridge.c
+++ b/cleopatre/application/managerd/src/bridge.c
@@ -89,27 +89,35 @@ enum bridge_status bridge_processing(struct managerd_ctx *ctx, uint8_t *buffer,
}
/**
- * Receive a frame from BR interface.
+ * Receive a frame from BR or LO interface.
*
* \param ctx managerd context.
* \param buffer frame pointer.
* \param len length allowed.
- * \return received length or error code.
+ * \param is_local boolean; TRUE: get packet from loopback, else: get packet from bridge
+ * \return received length or error code.
*/
-int bridge_receive(struct managerd_ctx *ctx, uint8_t *buffer, int len)
+int bridge_receive(struct managerd_ctx *ctx, uint8_t *buffer, int len, int is_local)
{
//Receive a raw packet from BR interface
- len = recv(ctx->sock_br, buffer, len, 0);
+ if(is_local)
+ {
+ len = recv(ctx->sock_lo, buffer, len, 0);
+ }
+ else
+ {
+ len = recv(ctx->sock_br, buffer, len, 0);
+ }
if(0 >= len)
{
- syslog(LOG_WARNING, "receive failed on %s (%s)", BR_IFNAME, strerror(errno));
+ syslog(LOG_WARNING, "receive failed on %s (%s)", is_local ? LO_IFNAME : BR_IFNAME, strerror(errno));
return -1;
}
return len;
}
/**
- * Send a frame to BR interface.
+ * Send a frame to BR or LO interface.
*
* \param ctx managerd context.
* \param buffer frame pointer.
@@ -119,11 +127,20 @@ int bridge_receive(struct managerd_ctx *ctx, uint8_t *buffer, int len)
int bridge_send(struct managerd_ctx *ctx, uint8_t *buffer, int len)
{
- //Send a raw packet to BR interface
- len = send(ctx->sock_br, buffer, len, 0);
+ struct ethhdr *ethhdr;
+ int is_local = 0;
+ ethhdr = (struct ethhdr *)buffer;
+
+ /* check destination mac address */
+ if(!memcmp (ethhdr->h_dest, ctx->br_mac_addr, ETH_ALEN))
+ {
+ is_local = 1;
+ }
+ //Send a raw packet to right interface
+ len = send (is_local ? ctx->sock_lo : ctx->sock_br, buffer, len, 0);
if(0 > len)
{
- syslog(LOG_WARNING, "send failed on %s (%s)", BR_IFNAME, strerror(errno));
+ syslog(LOG_WARNING, "send failed on %s (%s)", is_local ? LO_IFNAME : BR_IFNAME, strerror(errno));
return -1;
}
return 0;
@@ -143,9 +160,6 @@ int bridge_init(struct managerd_ctx *ctx)
//Check arguments
assert(ctx != NULL);
- //Set context
- ctx->br_sll_sz = (socklen_t)(sizeof(struct sockaddr_ll));
-
//Create a receive connection on BR interface
if(0 > (ctx->sock_br = socket(AF_PACKET, SOCK_RAW, ETH_P_HPAV)))
{
@@ -154,25 +168,25 @@ int bridge_init(struct managerd_ctx *ctx)
}
//Prepare BR socket address
- strncpy(ctx->br_ifr.ifr_name, (char*)BR_IFNAME, IFNAMSIZ);
- if(-1 == (ioctl(ctx->sock_br, SIOCGIFINDEX, &ctx->br_ifr)))
+ strncpy(ifr.ifr_name, (char*)BR_IFNAME, IFNAMSIZ);
+ if(-1 == (ioctl(ctx->sock_br, SIOCGIFINDEX, &ifr)))
{
syslog(LOG_WARNING, "cannot get interface %s index (%s)", BR_IFNAME, strerror(errno));
close(ctx->sock_br);
return -1;
}
ctx->br_sll.sll_family = AF_PACKET;
- ctx->br_sll.sll_ifindex = ctx->br_ifr.ifr_ifindex;
+ ctx->br_sll.sll_ifindex = ifr.ifr_ifindex;
ctx->br_sll.sll_protocol = htons(ETH_P_HPAV);
//Find BR mac address
- if(-1 == (ioctl(ctx->sock_br, SIOCGIFHWADDR, &ctx->br_ifr)))
+ if(-1 == (ioctl(ctx->sock_br, SIOCGIFHWADDR, &ifr)))
{
syslog(LOG_WARNING, "cannot get interface %s mac address (%s)", BR_IFNAME, strerror(errno));
close(ctx->sock_br);
return -1;
}
- memcpy(ctx->br_mac_addr, ctx->br_ifr.ifr_hwaddr.sa_data, ETH_ALEN);
+ memcpy(ctx->br_mac_addr, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
//Bind BR socket to this interface
if(-1 == (bind(ctx->sock_br, (struct sockaddr *)&ctx->br_sll, sizeof(struct sockaddr_ll))))
@@ -182,6 +196,36 @@ int bridge_init(struct managerd_ctx *ctx)
return -1;
}
+ //Create a receive connection on LO interface
+ if(0 > (ctx->sock_lo = socket(AF_PACKET, SOCK_RAW, ETH_P_HPAV)))
+ {
+ syslog(LOG_WARNING, "cannot open socket on %s (%s)", LO_IFNAME, strerror(errno));
+ close(ctx->sock_br);
+ return -1;
+ }
+
+ //Prepare LO socket address
+ strncpy(ifr.ifr_name, (char*)LO_IFNAME, IFNAMSIZ);
+ if(-1 == (ioctl(ctx->sock_lo, SIOCGIFINDEX, &ifr)))
+ {
+ syslog(LOG_WARNING, "cannot get interface %s index (%s)", LO_IFNAME, strerror(errno));
+ close(ctx->sock_br);
+ close(ctx->sock_lo);
+ return -1;
+ }
+ sll.sll_family = AF_PACKET;
+ sll.sll_ifindex = ifr.ifr_ifindex;
+ sll.sll_protocol = htons(ETH_P_HPAV);
+
+ //Bind LO socket to this interface
+ if(-1 == (bind(ctx->sock_lo, (struct sockaddr *)&sll, sizeof(struct sockaddr_ll))))
+ {
+ syslog(LOG_WARNING, "cannot bind raw socket to interface %s (%s)", LO_IFNAME, strerror(errno));
+ close(ctx->sock_lo);
+ close(ctx->sock_br);
+ return -1;
+ }
+
return 0;
}
@@ -197,5 +241,6 @@ void bridge_uninit(struct managerd_ctx *ctx)
//Close BR connections
close(ctx->sock_br);
+ //Close LO connections
+ close(ctx->sock_lo);
}
-
diff --git a/cleopatre/application/managerd/src/managerd.c b/cleopatre/application/managerd/src/managerd.c
index 0db0e3cdbb..4944cf21b0 100644
--- a/cleopatre/application/managerd/src/managerd.c
+++ b/cleopatre/application/managerd/src/managerd.c
@@ -68,10 +68,11 @@ static int managerd_process(struct managerd_ctx *ctx)
timeout.tv_usec = 0;
FD_ZERO(&readfds);
FD_SET(ctx->sock_br, &readfds);
+ FD_SET(ctx->sock_lo, &readfds);
FD_SET (ctx->sock_mme, &readfds);
- //Select on BR connection
- result = select(ctx->sock_br + 2, &readfds, NULL, NULL, &timeout);
+ //Select
+ result = select(ctx->sock_br + 3, &readfds, NULL, NULL, &timeout);
//Select error
if(0 > result)
@@ -88,10 +89,11 @@ static int managerd_process(struct managerd_ctx *ctx)
else
continue;
}
- else if FD_ISSET (ctx->sock_br, &readfds)
+ else if (FD_ISSET (ctx->sock_br, &readfds)
+ || FD_ISSET (ctx->sock_lo, &readfds))
{
//Receive a frame from bridge: process it
- len = bridge_receive(ctx, buffer, MAX_PKT_LEN);
+ len = bridge_receive(ctx, buffer, MAX_PKT_LEN, FD_ISSET (ctx->sock_lo, &readfds) /* check for local if */);
if(0 >= len)
{
result = -1;