Revision 62e64905 proto/static/static.c

View differences:

proto/static/static.c
60 60
static void
61 61
static_install(struct proto *p, struct static_route *r)
62 62
{
63
  rta *ap = alloca(RTA_MAX_SIZE);
63
  rta *ap = allocz(RTA_MAX_SIZE);
64 64
  rte *e;
65 65

  
66 66
  if (!(r->state & STS_WANT) && (r->state & (STS_INSTALLED | STS_FORCE)) && r->dest != RTD_UNICAST)
67 67
    goto drop;
68 68

  
69 69
  DBG("Installing static route %N, rtd=%d\n", r->net, r->dest);
70
  bzero(ap, RTA_MAX_SIZE);
71 70
  ap->src = p->main_source;
72
  ap->source = ((r->dest == RTD_UNICAST) && ipa_zero(r->via)) ? RTS_STATIC_DEVICE : RTS_STATIC;
71
  ap->source = RTS_STATIC;
73 72
  ap->scope = SCOPE_UNIVERSE;
74 73
  ap->dest = r->dest;
75 74

  
76 75
  if (r->dest == RTD_UNICAST)
77 76
    {
77
      struct nexthop *nhs = NULL;
78 78
      struct static_route *r2;
79
      int num = 0, update = 0;
79
      int update = 0;
80 80

  
81
      r = r->mp_head;
81 82
      for (r2 = r; r2; r2 = r2->mp_next)
82 83
      {
83

  
84 84
	if ((r2->state & STS_FORCE) ||
85 85
	    (!!(r2->state & STS_INSTALLED) != !!(r2->state & STS_WANT)))
86 86
	  update++;
87 87

  
88 88
	if (r2->state & STS_WANT)
89
	  {
90
	    struct nexthop *nh = (ap->nh.next) ? alloca(NEXTHOP_MAX_SIZE) : &(ap->nh);
91
	    if (ipa_zero(r2->via)) // Device nexthop
92
	      {
93
		nh->gw = IPA_NONE;
94
		nh->iface = r2->iface;
95
	      }
96
	    else // Router nexthop
97
	      {
98
		nh->gw = r2->via;
99
		nh->iface = r2->neigh->iface;
100
	      }
101
	    nh->weight = r2->weight;
102
	    nh->labels = r2->label_count;
103
	    for (int i=0; i<nh->labels; i++)
104
	      nh->label[i] = r2->label_stack[i];
105

  
106
	    if (ap->nh.next)
107
	      nexthop_insert(&(ap->nh), nh);
108
	    r2->state |= STS_INSTALLED;
109
	    num++;
110
	  }
89
	{
90
	  struct nexthop *nh = allocz(NEXTHOP_MAX_SIZE);
91

  
92
	  nh->gw = r2->via;
93
	  nh->iface = r2->neigh ? r2->neigh->iface : r2->iface;
94
	  nh->weight = r2->weight;
95
	  nh->labels = r2->label_count;
96
	  memcpy(nh->label, r2->label_stack, r2->label_count * sizeof(u32));
97

  
98
	  r2->state |= STS_INSTALLED;
99
	  nexthop_insert(&nhs, nh);
100
	}
111 101
	else
112 102
	  r2->state = 0;
113 103
      }
......
115 105
      if (!update) // Nothing changed
116 106
	return;
117 107

  
118
      r = r->mp_head;
119

  
120
      if (!num) // No nexthop to install
108
      if (!nhs) // No nexthop to install
121 109
      {
122 110
drop:
123 111
	rte_update(p, r->net, NULL);
124 112
	return;
125 113
      }
114

  
115
      ap->dest = RTD_UNICAST;
116
      nexthop_link(ap, nhs);
126 117
    }
127 118
  else
128 119
    r->state |= STS_INSTALLED;
129
  
120

  
130 121
  if (r->dest == RTDX_RECURSIVE)
131 122
    {
132 123
      ap->nh.labels_append = ap->nh.labels = r->label_count;

Also available in: Unified diff