summaryrefslogtreecommitdiff
path: root/accel-pppd/ppp/ipcp_opt_ipaddr.c
diff options
context:
space:
mode:
Diffstat (limited to 'accel-pppd/ppp/ipcp_opt_ipaddr.c')
-rw-r--r--accel-pppd/ppp/ipcp_opt_ipaddr.c51
1 files changed, 34 insertions, 17 deletions
diff --git a/accel-pppd/ppp/ipcp_opt_ipaddr.c b/accel-pppd/ppp/ipcp_opt_ipaddr.c
index 3a3f6db6..14557440 100644
--- a/accel-pppd/ppp/ipcp_opt_ipaddr.c
+++ b/accel-pppd/ppp/ipcp_opt_ipaddr.c
@@ -82,31 +82,41 @@ static int check_exists(struct ppp_t *self_ppp, in_addr_t addr)
return r;
}
+static int alloc_ip(struct ppp_t *ppp)
+{
+ ppp->ipv4 = ipdb_get_ipv4(ppp);
+ if (!ppp->ipv4) {
+ log_ppp_warn("ppp: no free IPv4 address\n");
+ return IPCP_OPT_CLOSE;
+ }
+
+ if (iprange_tunnel_check(ppp->ipv4->peer_addr)) {
+ log_ppp_warn("ppp:ipcp: to avoid kernel soft lockup requested IP cannot be assigned (%i.%i.%i.%i)\n",
+ ppp->ipv4->peer_addr&0xff,
+ (ppp->ipv4->peer_addr >> 8)&0xff,
+ (ppp->ipv4->peer_addr >> 16)&0xff,
+ (ppp->ipv4->peer_addr >> 24)&0xff);
+ return IPCP_OPT_FAIL;
+ }
+
+ if (conf_check_exists && check_exists(ppp, ppp->ipv4->peer_addr))
+ return IPCP_OPT_FAIL;
+
+ return 0;
+}
+
static int ipaddr_send_conf_req(struct ppp_ipcp_t *ipcp, struct ipcp_option_t *opt, uint8_t *ptr)
{
struct ipaddr_option_t *ipaddr_opt = container_of(opt, typeof(*ipaddr_opt), opt);
struct ipcp_opt32_t *opt32 = (struct ipcp_opt32_t *)ptr;
+ int r;
if (!ipcp->ppp->ipv4) {
- ipcp->ppp->ipv4 = ipdb_get_ipv4(ipcp->ppp);
- if (!ipcp->ppp->ipv4) {
- log_ppp_warn("ppp: no free IPv4 address\n");
- return -1;
- }
- }
-
- if (iprange_tunnel_check(ipcp->ppp->ipv4->peer_addr)) {
- log_ppp_warn("ppp:ipcp: to avoid kernel soft lockup requested IP cannot be assigned (%i.%i.%i.%i)\n",
- ipcp->ppp->ipv4->peer_addr&0xff,
- (ipcp->ppp->ipv4->peer_addr >> 8)&0xff,
- (ipcp->ppp->ipv4->peer_addr >> 16)&0xff,
- (ipcp->ppp->ipv4->peer_addr >> 24)&0xff);
- return -1;
+ r = alloc_ip(ipcp->ppp);
+ if (r)
+ return r;
}
- if (conf_check_exists && check_exists(ipcp->ppp, ipcp->ppp->ipv4->peer_addr))
- return -1;
-
opt32->hdr.id = CI_ADDR;
opt32->hdr.len = 6;
opt32->val = ipcp->ppp->ipv4->addr;
@@ -129,6 +139,13 @@ static int ipaddr_recv_conf_req(struct ppp_ipcp_t *ipcp, struct ipcp_option_t *o
struct ipcp_opt32_t *opt32 = (struct ipcp_opt32_t *)ptr;
struct ifreq ifr;
struct sockaddr_in addr;
+ int r;
+
+ if (!ipcp->ppp->ipv4) {
+ r = alloc_ip(ipcp->ppp);
+ if (r)
+ return r;
+ }
if (opt32->hdr.len != 6)
return IPCP_OPT_REJ;